rails-active-mcp 2.0.8 → 2.0.12
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/.rubocop.yml +141 -0
- data/README.md +3 -3
- data/exe/rails-active-mcp-server +8 -8
- data/gemfiles/rails_6.0.gemfile +34 -0
- data/gemfiles/rails_6.1.gemfile +34 -0
- data/gemfiles/rails_7.0.gemfile +34 -0
- data/gemfiles/rails_7.1.gemfile +22 -22
- data/gemfiles/rails_7.2.gemfile +34 -0
- data/lib/generators/rails_active_mcp/install/install_generator.rb +44 -94
- data/lib/generators/rails_active_mcp/install/templates/rails-active-mcp-server +104 -0
- data/lib/generators/rails_active_mcp/install/templates/rails-active-mcp-wrapper +94 -0
- data/lib/rails_active_mcp/configuration.rb +44 -4
- data/lib/rails_active_mcp/console_executor.rb +185 -83
- data/lib/rails_active_mcp/engine.rb +2 -2
- data/lib/rails_active_mcp/garbage_collection_utils.rb +13 -0
- data/lib/rails_active_mcp/safety_checker.rb +17 -7
- data/lib/rails_active_mcp/sdk/server.rb +1 -1
- data/lib/rails_active_mcp/sdk/tools/console_execute_tool.rb +0 -2
- data/lib/rails_active_mcp/sdk/tools/dry_run_tool.rb +0 -2
- data/lib/rails_active_mcp/sdk/tools/model_info_tool.rb +1 -3
- data/lib/rails_active_mcp/sdk/tools/safe_query_tool.rb +0 -2
- data/lib/rails_active_mcp/tasks.rake +6 -6
- data/lib/rails_active_mcp/version.rb +1 -1
- data/lib/rails_active_mcp.rb +4 -3
- data/mcp.ru +2 -2
- data/rails_active_mcp.gemspec +4 -4
- metadata +11 -3
@@ -0,0 +1,104 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Rails Active MCP Server Script
|
5
|
+
# This script starts the Rails Active MCP server for your Rails application
|
6
|
+
|
7
|
+
# Ensure we're in the Rails application directory
|
8
|
+
unless File.exist?('config/environment.rb') && File.exist?('Gemfile')
|
9
|
+
puts 'Error: This script must be run from the root of a Rails application'
|
10
|
+
puts "Current directory: #{Dir.pwd}"
|
11
|
+
puts 'Please ensure you have both config/environment.rb and Gemfile in your project root'
|
12
|
+
exit(1)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Load bundler and ensure the gem is available
|
16
|
+
begin
|
17
|
+
require 'bundler/setup'
|
18
|
+
rescue LoadError => e
|
19
|
+
puts "Error: Bundler not available: #{e.message}"
|
20
|
+
puts 'Please run: gem install bundler'
|
21
|
+
exit(1)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Check if rails-active-mcp is in the bundle
|
25
|
+
begin
|
26
|
+
gem 'rails-active-mcp'
|
27
|
+
rescue Gem::LoadError
|
28
|
+
puts 'Error: rails-active-mcp gem not found in bundle'
|
29
|
+
puts "Please add to your Gemfile: gem 'rails-active-mcp'"
|
30
|
+
puts 'Then run: bundle install'
|
31
|
+
exit(1)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Load Rails environment
|
35
|
+
begin
|
36
|
+
require_relative '../config/environment'
|
37
|
+
rescue LoadError => e
|
38
|
+
puts "Error: Failed to load Rails environment: #{e.message}"
|
39
|
+
puts 'Please ensure your Rails application is properly configured'
|
40
|
+
exit(1)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Load Rails Active MCP
|
44
|
+
begin
|
45
|
+
require 'rails_active_mcp'
|
46
|
+
rescue LoadError => e
|
47
|
+
puts "Error: Failed to load Rails Active MCP: #{e.message}"
|
48
|
+
puts 'Please ensure the gem is properly installed'
|
49
|
+
exit(1)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Ensure configuration is loaded
|
53
|
+
unless RailsActiveMcp.configuration
|
54
|
+
puts 'Warning: Rails Active MCP configuration not found'
|
55
|
+
puts 'Please run: rails generate rails_active_mcp:install'
|
56
|
+
puts 'Using default configuration...'
|
57
|
+
RailsActiveMcp.configure
|
58
|
+
end
|
59
|
+
|
60
|
+
# Start the server
|
61
|
+
begin
|
62
|
+
require 'rails_active_mcp/sdk/server'
|
63
|
+
|
64
|
+
# Parse command line arguments
|
65
|
+
transport = ARGV[0] || 'stdio'
|
66
|
+
|
67
|
+
case transport
|
68
|
+
when 'stdio', nil
|
69
|
+
puts 'Starting Rails Active MCP Server in stdio mode...' if ENV['RAILS_MCP_DEBUG']
|
70
|
+
server = RailsActiveMcp::Sdk::Server.new
|
71
|
+
server.run_stdio
|
72
|
+
when '--help', '-h'
|
73
|
+
puts <<~HELP
|
74
|
+
Rails Active MCP Server
|
75
|
+
|
76
|
+
Usage: #{File.basename($PROGRAM_NAME)} [mode] [options]
|
77
|
+
|
78
|
+
Modes:
|
79
|
+
stdio Start in stdio mode for MCP integration (default)
|
80
|
+
--help Show this help message
|
81
|
+
|
82
|
+
Environment Variables:
|
83
|
+
RAILS_MCP_DEBUG=1 Enable debug logging
|
84
|
+
RAILS_ENV=env Set Rails environment (default: development)
|
85
|
+
|
86
|
+
Examples:
|
87
|
+
#{File.basename($PROGRAM_NAME)} # Start in stdio mode
|
88
|
+
#{File.basename($PROGRAM_NAME)} stdio # Start in stdio mode explicitly
|
89
|
+
RAILS_MCP_DEBUG=1 #{File.basename($PROGRAM_NAME)} # Start with debug logging
|
90
|
+
HELP
|
91
|
+
else
|
92
|
+
puts "Error: Unknown transport mode '#{transport}'"
|
93
|
+
puts 'Use --help for usage information'
|
94
|
+
exit(1)
|
95
|
+
end
|
96
|
+
rescue Interrupt
|
97
|
+
puts "\nServer stopped by user"
|
98
|
+
exit(0)
|
99
|
+
rescue StandardError => e
|
100
|
+
puts "Error: Failed to start server: #{e.message}"
|
101
|
+
puts 'Backtrace:' if ENV['RAILS_MCP_DEBUG']
|
102
|
+
puts e.backtrace if ENV['RAILS_MCP_DEBUG']
|
103
|
+
exit(1)
|
104
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# Rails Active MCP Wrapper Script
|
4
|
+
# This script ensures Rails Active MCP works reliably across different Ruby version managers
|
5
|
+
|
6
|
+
# Function to detect Ruby version manager
|
7
|
+
detect_ruby_manager() {
|
8
|
+
if command -v asdf >/dev/null 2>&1 && [ -f .tool-versions ]; then
|
9
|
+
echo "asdf"
|
10
|
+
elif command -v rbenv >/dev/null 2>&1 && [ -f .ruby-version ]; then
|
11
|
+
echo "rbenv"
|
12
|
+
elif command -v rvm >/dev/null 2>&1 && [ -f .rvmrc ]; then
|
13
|
+
echo "rvm"
|
14
|
+
else
|
15
|
+
echo "system"
|
16
|
+
fi
|
17
|
+
}
|
18
|
+
|
19
|
+
# Function to setup environment for different Ruby managers
|
20
|
+
setup_ruby_environment() {
|
21
|
+
local manager=$1
|
22
|
+
|
23
|
+
case $manager in
|
24
|
+
"asdf")
|
25
|
+
if [ -n "$ASDF_DIR" ] && [ -f "$ASDF_DIR/asdf.sh" ]; then
|
26
|
+
source "$ASDF_DIR/asdf.sh"
|
27
|
+
elif [ -f "$HOME/.asdf/asdf.sh" ]; then
|
28
|
+
export ASDF_DIR="$HOME/.asdf"
|
29
|
+
source "$HOME/.asdf/asdf.sh"
|
30
|
+
fi
|
31
|
+
;;
|
32
|
+
"rbenv")
|
33
|
+
if [ -n "$RBENV_ROOT" ] && [ -f "$RBENV_ROOT/bin/rbenv" ]; then
|
34
|
+
export PATH="$RBENV_ROOT/bin:$PATH"
|
35
|
+
eval "$(rbenv init -)"
|
36
|
+
elif [ -f "$HOME/.rbenv/bin/rbenv" ]; then
|
37
|
+
export PATH="$HOME/.rbenv/bin:$PATH"
|
38
|
+
eval "$(rbenv init -)"
|
39
|
+
fi
|
40
|
+
;;
|
41
|
+
"rvm")
|
42
|
+
if [ -f "$HOME/.rvm/scripts/rvm" ]; then
|
43
|
+
source "$HOME/.rvm/scripts/rvm"
|
44
|
+
fi
|
45
|
+
;;
|
46
|
+
esac
|
47
|
+
}
|
48
|
+
|
49
|
+
# Get the directory where this script is located
|
50
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
51
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
52
|
+
|
53
|
+
# Change to the Rails project directory
|
54
|
+
cd "$PROJECT_ROOT" || {
|
55
|
+
echo "Error: Cannot change to project root directory: $PROJECT_ROOT" >&2
|
56
|
+
exit 1
|
57
|
+
}
|
58
|
+
|
59
|
+
# Detect and setup Ruby environment
|
60
|
+
RUBY_MANAGER=$(detect_ruby_manager)
|
61
|
+
setup_ruby_environment "$RUBY_MANAGER"
|
62
|
+
|
63
|
+
# Verify we have the necessary files
|
64
|
+
if [ ! -f "Gemfile" ]; then
|
65
|
+
echo "Error: Gemfile not found in $PROJECT_ROOT" >&2
|
66
|
+
echo "Please ensure you're running this from a Rails application root" >&2
|
67
|
+
exit 1
|
68
|
+
fi
|
69
|
+
|
70
|
+
if [ ! -f "config/environment.rb" ]; then
|
71
|
+
echo "Warning: config/environment.rb not found. This may not be a Rails application." >&2
|
72
|
+
fi
|
73
|
+
|
74
|
+
# Set default environment if not specified
|
75
|
+
export RAILS_ENV="${RAILS_ENV:-development}"
|
76
|
+
|
77
|
+
# Ensure we have the rails-active-mcp gem available
|
78
|
+
if ! bundle list | grep -q "rails-active-mcp"; then
|
79
|
+
echo "Error: rails-active-mcp gem not found in bundle" >&2
|
80
|
+
echo "Please run: bundle install" >&2
|
81
|
+
exit 1
|
82
|
+
fi
|
83
|
+
|
84
|
+
# Execute the Rails Active MCP server
|
85
|
+
# Try bundle exec first, then fall back to direct execution
|
86
|
+
if bundle exec rails-active-mcp-server "$@" 2>/dev/null; then
|
87
|
+
exit 0
|
88
|
+
elif command -v rails-active-mcp-server >/dev/null 2>&1; then
|
89
|
+
exec rails-active-mcp-server "$@"
|
90
|
+
else
|
91
|
+
echo "Error: Cannot find rails-active-mcp-server executable" >&2
|
92
|
+
echo "Please ensure the rails-active-mcp gem is properly installed" >&2
|
93
|
+
exit 1
|
94
|
+
fi
|
@@ -8,7 +8,7 @@ module RailsActiveMcp
|
|
8
8
|
attr_accessor :allowed_commands, :command_timeout, :enable_logging, :log_level
|
9
9
|
|
10
10
|
# Safety and execution options
|
11
|
-
attr_accessor :safe_mode, :
|
11
|
+
attr_accessor :safe_mode, :max_results, :log_executions, :audit_file, :enabled
|
12
12
|
attr_accessor :custom_safety_patterns, :allowed_models
|
13
13
|
|
14
14
|
def initialize
|
@@ -24,12 +24,12 @@ module RailsActiveMcp
|
|
24
24
|
|
25
25
|
# Safety and execution defaults
|
26
26
|
@safe_mode = true
|
27
|
-
@default_timeout = 30
|
28
27
|
@max_results = 100
|
29
28
|
@log_executions = false
|
30
29
|
@audit_file = nil
|
31
30
|
@custom_safety_patterns = []
|
32
31
|
@allowed_models = []
|
32
|
+
@enabled = true
|
33
33
|
end
|
34
34
|
|
35
35
|
def model_allowed?(model_name)
|
@@ -44,15 +44,55 @@ module RailsActiveMcp
|
|
44
44
|
[true, false].include?(enable_logging) &&
|
45
45
|
%i[debug info warn error].include?(log_level) &&
|
46
46
|
[true, false].include?(safe_mode) &&
|
47
|
-
default_timeout.is_a?(Numeric) && default_timeout > 0 &&
|
48
47
|
max_results.is_a?(Numeric) && max_results > 0 &&
|
49
48
|
[true, false].include?(log_executions) &&
|
50
49
|
custom_safety_patterns.is_a?(Array) &&
|
51
|
-
allowed_models.is_a?(Array)
|
50
|
+
allowed_models.is_a?(Array) &&
|
51
|
+
[true, false].include?(enabled)
|
52
|
+
end
|
53
|
+
|
54
|
+
def validate?
|
55
|
+
raise ArgumentError, 'allowed_commands must be an array' unless allowed_commands.is_a?(Array)
|
56
|
+
|
57
|
+
raise ArgumentError, 'command_timeout must be positive' unless command_timeout.is_a?(Numeric) && command_timeout > 0
|
58
|
+
|
59
|
+
raise ArgumentError, 'log_level must be one of: debug, info, warn, error' unless %i[debug info warn error].include?(log_level)
|
60
|
+
|
61
|
+
raise ArgumentError, 'safe_mode must be a boolean' unless [true, false].include?(safe_mode)
|
62
|
+
|
63
|
+
raise ArgumentError, 'max_results must be positive' unless max_results.is_a?(Numeric) && max_results > 0
|
64
|
+
|
65
|
+
raise ArgumentError, 'enabled must be a boolean' unless [true, false].include?(enabled)
|
66
|
+
|
67
|
+
true
|
52
68
|
end
|
53
69
|
|
54
70
|
def reset!
|
55
71
|
initialize
|
56
72
|
end
|
73
|
+
|
74
|
+
# Environment-specific configuration presets
|
75
|
+
def production_mode!
|
76
|
+
@safe_mode = true
|
77
|
+
@log_level = :warn
|
78
|
+
@command_timeout = 15
|
79
|
+
@max_results = 50
|
80
|
+
@log_executions = true
|
81
|
+
end
|
82
|
+
|
83
|
+
def development_mode!
|
84
|
+
@safe_mode = false
|
85
|
+
@log_level = :debug
|
86
|
+
@command_timeout = 60
|
87
|
+
@max_results = 200
|
88
|
+
@log_executions = false
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_mode!
|
92
|
+
@safe_mode = true
|
93
|
+
@log_level = :error
|
94
|
+
@command_timeout = 30
|
95
|
+
@log_executions = false
|
96
|
+
end
|
57
97
|
end
|
58
98
|
end
|