rails-active-mcp 0.1.7 โ 2.0.8
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 +106 -279
- data/changelog.md +69 -0
- data/docs/DEBUGGING.md +5 -5
- data/docs/README.md +130 -142
- data/examples/rails_app_integration.md +405 -0
- data/exe/rails-active-mcp-server +153 -76
- data/gemfiles/rails_7.1.gemfile +34 -0
- data/lib/generators/rails_active_mcp/install/install_generator.rb +19 -39
- data/lib/generators/rails_active_mcp/install/templates/README.md +134 -188
- data/lib/generators/rails_active_mcp/install/templates/initializer.rb +65 -28
- data/lib/generators/rails_active_mcp/install/templates/mcp.ru +7 -3
- data/lib/rails_active_mcp/configuration.rb +37 -98
- data/lib/rails_active_mcp/console_executor.rb +13 -3
- data/lib/rails_active_mcp/engine.rb +36 -24
- data/lib/rails_active_mcp/sdk/server.rb +183 -0
- data/lib/rails_active_mcp/sdk/tools/console_execute_tool.rb +103 -0
- data/lib/rails_active_mcp/sdk/tools/dry_run_tool.rb +73 -0
- data/lib/rails_active_mcp/sdk/tools/model_info_tool.rb +106 -0
- data/lib/rails_active_mcp/sdk/tools/safe_query_tool.rb +77 -0
- data/lib/rails_active_mcp/tasks.rake +236 -80
- data/lib/rails_active_mcp/version.rb +1 -1
- data/lib/rails_active_mcp.rb +5 -11
- data/rails_active_mcp.gemspec +62 -11
- metadata +83 -24
- data/app/controllers/rails_active_mcp/mcp_controller.rb +0 -80
- data/lib/rails_active_mcp/mcp_server.rb +0 -383
- data/lib/rails_active_mcp/railtie.rb +0 -70
- data/lib/rails_active_mcp/stdio_server.rb +0 -517
- data/lib/rails_active_mcp/tools/console_execute_tool.rb +0 -61
- data/lib/rails_active_mcp/tools/dry_run_tool.rb +0 -41
- data/lib/rails_active_mcp/tools/model_info_tool.rb +0 -70
- data/lib/rails_active_mcp/tools/safe_query_tool.rb +0 -41
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mcp'
|
4
|
+
|
5
|
+
module RailsActiveMcp
|
6
|
+
module Sdk
|
7
|
+
module Tools
|
8
|
+
class ModelInfoTool < MCP::Tool
|
9
|
+
description 'Get information about Rails models including schema and associations'
|
10
|
+
|
11
|
+
input_schema(
|
12
|
+
properties: {
|
13
|
+
model: {
|
14
|
+
type: 'string',
|
15
|
+
description: 'Model class name'
|
16
|
+
},
|
17
|
+
include_schema: {
|
18
|
+
type: 'boolean',
|
19
|
+
description: 'Include database schema information'
|
20
|
+
},
|
21
|
+
include_associations: {
|
22
|
+
type: 'boolean',
|
23
|
+
description: 'Include model associations'
|
24
|
+
},
|
25
|
+
include_validations: {
|
26
|
+
type: 'boolean',
|
27
|
+
description: 'Include model validations'
|
28
|
+
}
|
29
|
+
},
|
30
|
+
required: ['model']
|
31
|
+
)
|
32
|
+
|
33
|
+
annotations(
|
34
|
+
title: 'Rails Model Inspector',
|
35
|
+
destructive_hint: false,
|
36
|
+
read_only_hint: true,
|
37
|
+
idempotent_hint: true,
|
38
|
+
open_world_hint: false
|
39
|
+
)
|
40
|
+
|
41
|
+
def self.call(model:, server_context:, include_schema: true, include_associations: true,
|
42
|
+
include_validations: true)
|
43
|
+
config = RailsActiveMcp.config
|
44
|
+
|
45
|
+
begin
|
46
|
+
model_class = model.constantize
|
47
|
+
|
48
|
+
output = []
|
49
|
+
output << "Model: #{model}"
|
50
|
+
output << "Table: #{model_class.table_name}"
|
51
|
+
output << "Primary Key: #{model_class.primary_key}"
|
52
|
+
|
53
|
+
if include_schema
|
54
|
+
output << "\nSchema:"
|
55
|
+
model_class.columns.each do |column|
|
56
|
+
output << " #{column.name}: #{column.type} (#{column.sql_type})"
|
57
|
+
output << " - Null: #{column.null}"
|
58
|
+
output << " - Default: #{column.default}" if column.default
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if include_associations
|
63
|
+
output << "\nAssociations:"
|
64
|
+
model_class.reflections.each do |name, reflection|
|
65
|
+
output << " #{name}: #{reflection.class.name.split('::').last} -> #{reflection.class_name}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
if include_validations
|
70
|
+
validations = {}
|
71
|
+
model_class.validators.each do |validator|
|
72
|
+
validator.attributes.each do |attribute|
|
73
|
+
validations[attribute] ||= []
|
74
|
+
validations[attribute] << validator.class.name.split('::').last
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
if validations.any?
|
79
|
+
output << "\nValidations:"
|
80
|
+
validations.each do |attr, validators|
|
81
|
+
output << " #{attr}: #{validators.join(', ')}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
MCP::Tool::Response.new([
|
87
|
+
{ type: 'text', text: output.join("\n") }
|
88
|
+
])
|
89
|
+
rescue NameError
|
90
|
+
error_response("Model '#{model}' not found")
|
91
|
+
rescue StandardError => e
|
92
|
+
error_response("Error analyzing model: #{e.message}")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def self.error_response(message)
|
99
|
+
MCP::Tool::Response.new([
|
100
|
+
{ type: 'text', text: message }
|
101
|
+
])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mcp'
|
4
|
+
|
5
|
+
module RailsActiveMcp
|
6
|
+
module Sdk
|
7
|
+
module Tools
|
8
|
+
class SafeQueryTool < MCP::Tool
|
9
|
+
description 'Execute safe read-only database queries on Rails models'
|
10
|
+
|
11
|
+
input_schema(
|
12
|
+
properties: {
|
13
|
+
model: {
|
14
|
+
type: 'string',
|
15
|
+
description: 'Model class name (e.g., "User", "Product")'
|
16
|
+
},
|
17
|
+
method: {
|
18
|
+
type: 'string',
|
19
|
+
description: 'Query method (find, where, count, etc.)'
|
20
|
+
},
|
21
|
+
args: {
|
22
|
+
type: 'array',
|
23
|
+
description: 'Arguments for the query method'
|
24
|
+
},
|
25
|
+
limit: {
|
26
|
+
type: 'integer',
|
27
|
+
description: 'Limit results (default: 100)'
|
28
|
+
}
|
29
|
+
},
|
30
|
+
required: %w[model method]
|
31
|
+
)
|
32
|
+
|
33
|
+
annotations(
|
34
|
+
title: 'Safe Query Executor',
|
35
|
+
destructive_hint: false,
|
36
|
+
read_only_hint: true,
|
37
|
+
idempotent_hint: true,
|
38
|
+
open_world_hint: false
|
39
|
+
)
|
40
|
+
|
41
|
+
def self.call(model:, method:, server_context:, args: [], limit: 100)
|
42
|
+
config = RailsActiveMcp.config
|
43
|
+
|
44
|
+
executor = RailsActiveMcp::ConsoleExecutor.new(config)
|
45
|
+
|
46
|
+
result = executor.execute_safe_query(
|
47
|
+
model: model,
|
48
|
+
method: method,
|
49
|
+
args: args,
|
50
|
+
limit: limit
|
51
|
+
)
|
52
|
+
|
53
|
+
if result[:success]
|
54
|
+
output = []
|
55
|
+
output << "Query: #{model}.#{method}(#{args.join(', ')})"
|
56
|
+
output << "Count: #{result[:count]}" if result[:count]
|
57
|
+
output << "Result: #{result[:result].inspect}"
|
58
|
+
|
59
|
+
MCP::Tool::Response.new([
|
60
|
+
{ type: 'text', text: output.join("\n") }
|
61
|
+
])
|
62
|
+
else
|
63
|
+
error_response(result[:error])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def self.error_response(message)
|
70
|
+
MCP::Tool::Response.new([
|
71
|
+
{ type: 'text', text: message }
|
72
|
+
])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
namespace :rails_active_mcp do
|
2
|
-
desc
|
2
|
+
desc 'Check the safety of Ruby code'
|
3
3
|
task :check_safety, [:code] => :environment do |task, args|
|
4
4
|
code = args[:code]
|
5
5
|
|
@@ -24,7 +24,7 @@ namespace :rails_active_mcp do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
desc
|
27
|
+
desc 'Execute Ruby code with safety checks'
|
28
28
|
task :execute, [:code] => :environment do |task, args|
|
29
29
|
code = args[:code]
|
30
30
|
|
@@ -44,111 +44,267 @@ namespace :rails_active_mcp do
|
|
44
44
|
puts "Error: #{result[:error]}"
|
45
45
|
puts "Error class: #{result[:error_class]}" if result[:error_class]
|
46
46
|
end
|
47
|
-
rescue => e
|
47
|
+
rescue StandardError => e
|
48
48
|
puts "Failed to execute: #{e.message}"
|
49
49
|
exit 1
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
desc
|
54
|
-
task :
|
55
|
-
puts
|
53
|
+
desc 'Test MCP tools'
|
54
|
+
task test_tools: :environment do
|
55
|
+
puts 'Testing Rails Active MCP tools...'
|
56
56
|
|
57
|
-
# Test
|
58
|
-
puts "\n1. Testing
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
# Test console execution
|
58
|
+
puts "\n1. Testing console_execute tool:"
|
59
|
+
result = RailsActiveMcp.execute('1 + 1')
|
60
|
+
puts " Simple math: #{result[:success] ? 'PASS' : 'FAIL'}"
|
61
|
+
|
62
|
+
# Test safety checking
|
63
|
+
puts "\n2. Testing safety checking:"
|
64
|
+
safe_result = RailsActiveMcp.safe?('User.count')
|
65
|
+
dangerous_result = RailsActiveMcp.safe?('User.delete_all')
|
66
|
+
puts " Safe code detection: #{safe_result ? 'PASS' : 'FAIL'}"
|
67
|
+
puts " Dangerous code detection: #{!dangerous_result ? 'PASS' : 'FAIL'}"
|
68
|
+
|
69
|
+
# Test Rails integration
|
70
|
+
puts "\n3. Testing Rails integration:"
|
71
|
+
if defined?(Rails) && Rails.respond_to?(:env)
|
72
|
+
puts " Rails environment: #{Rails.env} - PASS"
|
63
73
|
else
|
64
|
-
puts
|
74
|
+
puts ' Rails environment: NOT DETECTED - FAIL'
|
65
75
|
end
|
66
76
|
|
67
|
-
|
68
|
-
|
69
|
-
tool = RailsActiveMcp::Tools::ConsoleExecuteTool.new
|
70
|
-
result = tool.call(code: "1 + 1")
|
71
|
-
puts " 1 + 1: #{result[:success] ? result[:return_value] : result[:error]}"
|
77
|
+
puts "\nAll tests completed!"
|
78
|
+
end
|
72
79
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
result = tool.call(code: "User.delete_all")
|
77
|
-
puts " User.delete_all analysis: #{result[:estimated_risk]} risk"
|
80
|
+
desc 'Benchmark MCP tools performance'
|
81
|
+
task benchmark: :environment do
|
82
|
+
require 'benchmark'
|
78
83
|
|
79
|
-
puts
|
80
|
-
|
84
|
+
puts 'Rails Active MCP Performance Benchmark'
|
85
|
+
puts '=' * 50
|
81
86
|
|
82
|
-
|
83
|
-
|
84
|
-
|
87
|
+
# Benchmark safety checking
|
88
|
+
puts "\nSafety Checker Performance:"
|
89
|
+
Benchmark.bm(20) do |x|
|
90
|
+
x.report('Simple check:') do
|
91
|
+
1000.times { RailsActiveMcp.safe?('User.count') }
|
92
|
+
end
|
85
93
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
puts " Default timeout: #{config.default_timeout}s"
|
90
|
-
puts " Max results: #{config.max_results}"
|
91
|
-
puts " Log executions: #{config.log_executions}"
|
92
|
-
puts " Audit file: #{config.audit_file}"
|
93
|
-
puts " Enable mutation tools: #{config.enable_mutation_tools}"
|
94
|
-
puts " Execution environment: #{config.execution_environment}"
|
94
|
+
x.report('Complex check:') do
|
95
|
+
100.times { RailsActiveMcp.safe?('User.where(active: true).includes(:posts).limit(10)') }
|
96
|
+
end
|
95
97
|
|
96
|
-
|
97
|
-
|
98
|
+
x.report('Dangerous check:') do
|
99
|
+
1000.times { RailsActiveMcp.safe?('User.delete_all') }
|
100
|
+
end
|
98
101
|
end
|
99
102
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
+
# Benchmark code execution
|
104
|
+
puts "\nCode Execution Performance:"
|
105
|
+
Benchmark.bm(20) do |x|
|
106
|
+
x.report('Simple math:') do
|
107
|
+
100.times { RailsActiveMcp.execute('1 + 1') }
|
108
|
+
end
|
103
109
|
|
104
|
-
|
105
|
-
|
110
|
+
x.report('String operations:') do
|
111
|
+
100.times { RailsActiveMcp.execute('"hello".upcase') }
|
112
|
+
end
|
106
113
|
end
|
107
114
|
end
|
108
115
|
|
109
|
-
desc
|
110
|
-
task :
|
111
|
-
|
112
|
-
|
116
|
+
desc 'Validate Rails Active MCP configuration'
|
117
|
+
task validate_config: :environment do
|
118
|
+
puts 'Validating Rails Active MCP configuration...'
|
119
|
+
|
120
|
+
config = RailsActiveMcp.config
|
121
|
+
|
122
|
+
if config.valid?
|
123
|
+
puts 'โ
Configuration is valid'
|
113
124
|
|
114
|
-
|
115
|
-
puts "
|
125
|
+
puts "\nCurrent Settings:"
|
126
|
+
puts " Safe mode: #{config.safe_mode}"
|
127
|
+
puts " Command timeout: #{config.command_timeout}s"
|
128
|
+
puts " Max results: #{config.max_results}"
|
129
|
+
puts " Log executions: #{config.log_executions}"
|
130
|
+
puts " Log level: #{config.log_level}"
|
131
|
+
puts " Allowed models: #{config.allowed_models.any? ? config.allowed_models.join(', ') : 'All models allowed'}"
|
132
|
+
puts " Custom safety patterns: #{config.custom_safety_patterns.length} patterns"
|
133
|
+
else
|
134
|
+
puts 'โ Configuration is invalid'
|
135
|
+
puts 'Please check your config/initializers/rails_active_mcp.rb file'
|
116
136
|
exit 1
|
117
137
|
end
|
138
|
+
end
|
139
|
+
|
140
|
+
desc 'Generate example usage documentation'
|
141
|
+
task generate_examples: :environment do
|
142
|
+
examples_file = Rails.root.join('doc', 'rails_active_mcp_examples.md')
|
143
|
+
FileUtils.mkdir_p(File.dirname(examples_file))
|
144
|
+
|
145
|
+
content = <<~MARKDOWN
|
146
|
+
# Rails Active MCP Usage Examples
|
147
|
+
|
148
|
+
Generated on #{Date.current}
|
149
|
+
|
150
|
+
## Safe Operations
|
151
|
+
|
152
|
+
These operations are considered safe and can be executed in safe mode:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
# Basic model queries
|
156
|
+
User.count
|
157
|
+
User.all.limit(10)
|
158
|
+
User.where(active: true)
|
159
|
+
User.find(1)
|
160
|
+
|
161
|
+
# Associations
|
162
|
+
User.includes(:posts).limit(5)
|
163
|
+
Post.joins(:user).where(users: { active: true })
|
164
|
+
|
165
|
+
# Aggregations
|
166
|
+
Order.sum(:total_amount)
|
167
|
+
User.group(:status).count
|
168
|
+
|
169
|
+
# System information
|
170
|
+
Rails.env
|
171
|
+
Rails.version
|
172
|
+
Time.current
|
173
|
+
```
|
174
|
+
|
175
|
+
## Dangerous Operations (Blocked in Safe Mode)
|
176
|
+
|
177
|
+
These operations are blocked when safe_mode is enabled:
|
118
178
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
179
|
+
```ruby
|
180
|
+
# Mass deletions
|
181
|
+
User.delete_all
|
182
|
+
User.destroy_all
|
183
|
+
|
184
|
+
# System commands
|
185
|
+
system('rm -rf /')
|
186
|
+
`ls -la`
|
187
|
+
|
188
|
+
# File operations
|
189
|
+
File.delete('important_file.txt')
|
190
|
+
FileUtils.rm_rf('/important/directory')
|
191
|
+
|
192
|
+
# Code evaluation
|
193
|
+
eval(user_input)
|
194
|
+
send(dynamic_method)
|
195
|
+
```
|
196
|
+
|
197
|
+
## Claude Desktop Usage Examples
|
198
|
+
|
199
|
+
Ask Claude these questions to interact with your Rails app:
|
200
|
+
|
201
|
+
- "How many users do we have?"
|
202
|
+
- "Show me the User model structure"
|
203
|
+
- "What are the most recent orders?"
|
204
|
+
- "Check if this code is safe: User.where(active: false).delete_all"
|
205
|
+
- "Find users created in the last week"
|
206
|
+
- "What associations does the Post model have?"
|
207
|
+
|
208
|
+
## Configuration Examples
|
209
|
+
|
210
|
+
### Development Configuration
|
211
|
+
```ruby
|
212
|
+
RailsActiveMcp.configure do |config|
|
213
|
+
config.safe_mode = false
|
214
|
+
config.log_level = :debug
|
215
|
+
config.command_timeout = 60
|
216
|
+
config.max_results = 200
|
139
217
|
end
|
140
|
-
|
218
|
+
```
|
219
|
+
|
220
|
+
### Production Configuration
|
221
|
+
```ruby
|
222
|
+
RailsActiveMcp.configure do |config|
|
223
|
+
config.safe_mode = true
|
224
|
+
config.log_level = :warn
|
225
|
+
config.command_timeout = 15
|
226
|
+
config.max_results = 50
|
227
|
+
config.allowed_models = %w[User Post Comment]
|
228
|
+
end
|
229
|
+
```
|
230
|
+
MARKDOWN
|
231
|
+
|
232
|
+
File.write(examples_file, content)
|
233
|
+
puts "Examples generated at: #{examples_file}"
|
141
234
|
end
|
142
235
|
|
143
|
-
desc
|
144
|
-
task :
|
145
|
-
|
236
|
+
desc 'Install Claude Desktop configuration'
|
237
|
+
task install_claude_config: :environment do
|
238
|
+
config_template = {
|
239
|
+
mcpServers: {
|
240
|
+
'rails-active-mcp' => {
|
241
|
+
command: Rails.root.join('bin', 'rails-active-mcp-wrapper').to_s,
|
242
|
+
cwd: Rails.root.to_s,
|
243
|
+
env: {
|
244
|
+
RAILS_ENV: Rails.env
|
245
|
+
}
|
246
|
+
}
|
247
|
+
}
|
248
|
+
}
|
146
249
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
250
|
+
puts 'Claude Desktop Configuration:'
|
251
|
+
puts JSON.pretty_generate(config_template)
|
252
|
+
puts ''
|
253
|
+
puts 'Add this to your Claude Desktop configuration file:'
|
254
|
+
puts ' macOS/Linux: ~/.config/claude-desktop/claude_desktop_config.json'
|
255
|
+
puts ' Windows: %APPDATA%\\Claude\\claude_desktop_config.json'
|
256
|
+
end
|
257
|
+
|
258
|
+
desc 'Show comprehensive status and diagnostics'
|
259
|
+
task status: :environment do
|
260
|
+
puts 'Rails Active MCP Status Report'
|
261
|
+
puts '=' * 50
|
262
|
+
|
263
|
+
# Basic environment info
|
264
|
+
puts "\n๐ Environment Information:"
|
265
|
+
puts " Rails version: #{Rails.version}"
|
266
|
+
puts " Ruby version: #{RUBY_VERSION}"
|
267
|
+
puts " Rails environment: #{Rails.env}"
|
268
|
+
puts " Rails Active MCP version: #{RailsActiveMcp::VERSION}"
|
269
|
+
|
270
|
+
# Configuration status
|
271
|
+
puts "\nโ๏ธ Configuration Status:"
|
272
|
+
config = RailsActiveMcp.config
|
273
|
+
puts " Valid: #{config.valid? ? 'โ
' : 'โ'}"
|
274
|
+
puts " Safe mode: #{config.safe_mode ? '๐ Enabled' : 'โ ๏ธ Disabled'}"
|
275
|
+
puts " Timeout: #{config.command_timeout}s"
|
276
|
+
puts " Max results: #{config.max_results}"
|
277
|
+
|
278
|
+
# File status
|
279
|
+
puts "\n๐ File Status:"
|
280
|
+
files_to_check = [
|
281
|
+
'bin/rails-active-mcp-server',
|
282
|
+
'bin/rails-active-mcp-wrapper',
|
283
|
+
'config/initializers/rails_active_mcp.rb'
|
284
|
+
]
|
285
|
+
|
286
|
+
files_to_check.each do |file|
|
287
|
+
full_path = Rails.root.join(file)
|
288
|
+
if File.exist?(full_path)
|
289
|
+
executable = File.executable?(full_path)
|
290
|
+
puts " #{file}: โ
#{executable ? '(executable)' : ''}"
|
291
|
+
else
|
292
|
+
puts " #{file}: โ Missing"
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
# Test basic functionality
|
297
|
+
puts "\n๐งช Functionality Test:"
|
298
|
+
begin
|
299
|
+
test_result = RailsActiveMcp.execute('1 + 1')
|
300
|
+
puts " Basic execution: #{test_result[:success] ? 'โ
' : 'โ'}"
|
301
|
+
rescue StandardError => e
|
302
|
+
puts " Basic execution: โ (#{e.message})"
|
152
303
|
end
|
304
|
+
|
305
|
+
puts "\n๐ Integration URLs:"
|
306
|
+
puts ' Documentation: https://github.com/goodpie/rails-active-mcp'
|
307
|
+
puts ' Issues: https://github.com/goodpie/rails-active-mcp/issues'
|
308
|
+
puts ' MCP Protocol: https://modelcontextprotocol.io'
|
153
309
|
end
|
154
|
-
end
|
310
|
+
end
|
data/lib/rails_active_mcp.rb
CHANGED
@@ -5,18 +5,17 @@ require_relative 'rails_active_mcp/version'
|
|
5
5
|
require_relative 'rails_active_mcp/configuration'
|
6
6
|
require_relative 'rails_active_mcp/safety_checker'
|
7
7
|
require_relative 'rails_active_mcp/console_executor'
|
8
|
-
|
8
|
+
|
9
|
+
# Load SDK server
|
10
|
+
require_relative 'rails_active_mcp/sdk/server'
|
9
11
|
|
10
12
|
# Load Engine for Rails integration
|
11
13
|
require_relative 'rails_active_mcp/engine' if defined?(Rails)
|
12
14
|
|
13
15
|
module RailsActiveMcp
|
14
16
|
class Error < StandardError; end
|
15
|
-
|
16
17
|
class SafetyError < Error; end
|
17
|
-
|
18
18
|
class ExecutionError < Error; end
|
19
|
-
|
20
19
|
class TimeoutError < Error; end
|
21
20
|
|
22
21
|
class << self
|
@@ -42,16 +41,11 @@ module RailsActiveMcp
|
|
42
41
|
ConsoleExecutor.new(config).execute(code, **options)
|
43
42
|
end
|
44
43
|
|
45
|
-
#
|
46
|
-
def server
|
47
|
-
@server ||= McpServer.new
|
48
|
-
end
|
49
|
-
|
50
|
-
# Logger accessor - configured by railtie or defaults to stderr
|
44
|
+
# Logger accessor - configured by engine or defaults to stderr
|
51
45
|
attr_accessor :logger
|
52
46
|
|
53
47
|
def logger
|
54
|
-
@logger ||= Logger.new(
|
48
|
+
@logger ||= Logger.new($stderr).tap do |logger|
|
55
49
|
logger.level = Logger::INFO
|
56
50
|
logger.formatter = proc do |severity, datetime, progname, msg|
|
57
51
|
"[#{datetime}] #{severity} -- RailsActiveMcp: #{msg}\n"
|