rails-active-mcp 0.1.6 → 2.0.7
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/claude_desktop_config.json +12 -0
- data/docs/DEBUGGING.md +40 -8
- data/docs/GENERATOR_TESTING.md +121 -0
- data/docs/README.md +130 -142
- data/exe/rails-active-mcp-server +176 -65
- data/lib/generators/rails_active_mcp/install/install_generator.rb +123 -3
- data/lib/generators/rails_active_mcp/install/templates/README.md +34 -128
- data/lib/generators/rails_active_mcp/install/templates/initializer.rb +37 -38
- 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 +202 -78
- data/lib/rails_active_mcp/engine.rb +36 -8
- 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/version.rb +1 -1
- data/lib/rails_active_mcp.rb +10 -11
- data/rails_active_mcp.gemspec +8 -4
- metadata +43 -17
- data/lib/rails_active_mcp/mcp_server.rb +0 -374
- data/lib/rails_active_mcp/railtie.rb +0 -48
- data/lib/rails_active_mcp/stdio_server.rb +0 -467
- 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
data/exe/rails-active-mcp-server
CHANGED
@@ -1,86 +1,197 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
4
|
+
# Require essential gems first
|
5
5
|
require 'json'
|
6
6
|
require 'stringio'
|
7
|
-
|
8
|
-
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
7
|
+
|
8
|
+
# CRITICAL: Redirect stdout IMMEDIATELY for stdio mode to prevent any output interference
|
9
|
+
# This must happen before any other gem loading
|
10
|
+
original_stdout = $stdout
|
11
|
+
original_stderr = $stderr
|
12
|
+
|
13
|
+
# Determine if we should redirect output (stdio mode or explicit request)
|
14
|
+
should_redirect = (ARGV.first == 'stdio' || ARGV.first.nil?) && !ENV['RAILS_MCP_DEBUG']
|
15
|
+
|
16
|
+
if should_redirect
|
17
|
+
# Create log directory early
|
18
|
+
log_dir = File.join(Dir.pwd, 'log')
|
19
|
+
Dir.mkdir(log_dir) unless Dir.exist?(log_dir)
|
20
|
+
|
21
|
+
# Redirect stderr to log file immediately, before any loading
|
22
|
+
stderr_log = File.join(log_dir, 'rails_mcp_stderr.log')
|
23
|
+
$stderr.reopen(stderr_log, 'a')
|
24
|
+
$stderr.sync = true
|
25
|
+
|
26
|
+
# Use StringIO to capture any unwanted stdout during loading
|
27
|
+
# We'll filter out non-JSON content later
|
28
|
+
captured_stdout = StringIO.new
|
29
|
+
$stdout = captured_stdout
|
30
|
+
end
|
31
|
+
|
32
|
+
# Initialize Rails environment if available (from current working directory)
|
33
|
+
rails_loaded = false
|
34
|
+
rails_load_error = nil
|
35
|
+
if File.exist?('config/environment.rb')
|
36
|
+
begin
|
37
|
+
require './config/environment'
|
38
|
+
rails_loaded = true
|
39
|
+
|
40
|
+
# Log successful Rails loading
|
41
|
+
warn "[#{Time.now}] [RAILS-MCP] INFO: Rails environment loaded successfully" if should_redirect
|
42
|
+
rescue StandardError => e
|
43
|
+
# Rails loading failed, continue without it
|
44
|
+
rails_load_error = e
|
45
|
+
# Log to stderr (which is already redirected if needed)
|
46
|
+
warn "[#{Time.now}] [RAILS-MCP] WARNING: Failed to load Rails environment: #{e.message}"
|
47
|
+
warn "[#{Time.now}] [RAILS-MCP] WARNING: #{e.backtrace.first(3).join("\n")}" if ENV['RAILS_MCP_DEBUG']
|
48
|
+
end
|
49
|
+
elsif should_redirect
|
50
|
+
warn "[#{Time.now}] [RAILS-MCP] INFO: No Rails environment found (config/environment.rb missing)"
|
51
|
+
end
|
52
|
+
|
53
|
+
# Restore stdout after Rails loading for stdio mode (stderr stays redirected)
|
54
|
+
if should_redirect
|
55
|
+
# Check if anything was captured during loading
|
56
|
+
captured_content = captured_stdout.string
|
57
|
+
unless captured_content.empty?
|
58
|
+
# Log any captured content to stderr for debugging
|
59
|
+
warn "[#{Time.now}] [RAILS-MCP] WARNING: Captured stdout during loading: #{captured_content.inspect}"
|
60
|
+
$stderr.flush
|
61
|
+
end
|
62
|
+
|
63
|
+
# Restore original stdout
|
64
|
+
$stdout = original_stdout
|
65
|
+
end
|
66
|
+
|
67
|
+
# Now load the gem
|
68
|
+
begin
|
69
|
+
require_relative '../lib/rails_active_mcp'
|
70
|
+
rescue LoadError => e
|
71
|
+
warn "[#{Time.now}] [RAILS-MCP] FATAL: Failed to load rails_active_mcp gem: #{e.message}"
|
72
|
+
exit(1)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Parse command line options
|
76
|
+
transport = ARGV[0] || 'stdio'
|
77
|
+
port = ARGV.include?('--port') ? ARGV[ARGV.index('--port') + 1].to_i : 3001
|
78
|
+
host = ARGV.include?('--host') ? ARGV[ARGV.index('--host') + 1] : 'localhost'
|
79
|
+
|
80
|
+
# Determine and set correct working directory
|
81
|
+
def find_rails_root(start_dir = Dir.pwd)
|
82
|
+
current_dir = start_dir
|
83
|
+
|
84
|
+
# Look for Gemfile and config/environment.rb up to 5 levels up
|
85
|
+
5.times do
|
86
|
+
gemfile_path = File.join(current_dir, 'Gemfile')
|
87
|
+
config_path = File.join(current_dir, 'config', 'environment.rb')
|
88
|
+
|
89
|
+
return current_dir if File.exist?(gemfile_path) && File.exist?(config_path)
|
90
|
+
|
91
|
+
parent_dir = File.dirname(current_dir)
|
92
|
+
break if parent_dir == current_dir # reached root
|
93
|
+
|
94
|
+
current_dir = parent_dir
|
95
|
+
end
|
96
|
+
|
97
|
+
nil
|
98
|
+
end
|
99
|
+
|
100
|
+
# Auto-detect Rails root and change directory if needed
|
101
|
+
rails_root = find_rails_root
|
102
|
+
if rails_root && rails_root != Dir.pwd
|
103
|
+
warn "[#{Time.now}] [RAILS-MCP] INFO: Detected Rails root at #{rails_root}, changing directory" if should_redirect
|
104
|
+
Dir.chdir(rails_root)
|
105
|
+
elsif rails_root.nil?
|
106
|
+
# Check if we're in the gem directory and need to find a Rails app
|
107
|
+
if File.basename(Dir.pwd) == 'rails-active-mcp-gem' || Dir.pwd.include?('rails-active-mcp-gem')
|
108
|
+
warn "[#{Time.now}] [RAILS-MCP] ERROR: Running from gem directory, not Rails application directory"
|
109
|
+
warn "[#{Time.now}] [RAILS-MCP] ERROR: Please run the server from your Rails application root directory"
|
110
|
+
warn "[#{Time.now}] [RAILS-MCP] ERROR: Example: cd /path/to/your/rails/app && /path/to/rails-active-mcp-gem/exe/rails-active-mcp-server stdio"
|
111
|
+
exit(1)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Final check for Gemfile in current directory
|
115
|
+
unless File.exist?('Gemfile')
|
116
|
+
warn "[#{Time.now}] [RAILS-MCP] ERROR: Could not locate Gemfile in current directory: #{Dir.pwd}"
|
117
|
+
warn "[#{Time.now}] [RAILS-MCP] ERROR: Please ensure you're running from a Rails application root directory"
|
118
|
+
warn "[#{Time.now}] [RAILS-MCP] ERROR: Current directory contents:"
|
119
|
+
Dir.entries('.').each { |entry| warn "[#{Time.now}] [RAILS-MCP] ERROR: #{entry}" unless entry.start_with?('.') }
|
120
|
+
exit(1)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Log the working directory for debugging
|
125
|
+
warn "[#{Time.now}] [RAILS-MCP] INFO: Working directory: #{Dir.pwd}" if should_redirect
|
126
|
+
warn "[#{Time.now}] [RAILS-MCP] INFO: Gemfile found: #{File.exist?('Gemfile')}" if should_redirect
|
29
127
|
|
30
128
|
case transport
|
31
129
|
when 'stdio'
|
32
|
-
# Stdio transport for Claude Desktop
|
33
|
-
require_relative '../lib/rails_active_mcp/stdio_server'
|
34
|
-
|
130
|
+
# Stdio transport for Claude Desktop using MCP SDK
|
35
131
|
begin
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
# Log to stderr but don't fail - the server can work without Rails
|
46
|
-
warn "Warning: Could not load Rails environment: #{e.message}"
|
47
|
-
ensure
|
48
|
-
$stdout = original_stdout
|
49
|
-
end
|
132
|
+
require_relative '../lib/rails_active_mcp/sdk/server'
|
133
|
+
|
134
|
+
# Log startup information
|
135
|
+
if should_redirect
|
136
|
+
warn "[#{Time.now}] [RAILS-MCP] INFO: Starting Rails Active MCP Server v#{RailsActiveMcp::VERSION}"
|
137
|
+
end
|
138
|
+
warn "[#{Time.now}] [RAILS-MCP] INFO: Rails loaded: #{rails_loaded}" if should_redirect
|
139
|
+
if rails_load_error && should_redirect
|
140
|
+
warn "[#{Time.now}] [RAILS-MCP] WARNING: Rails load error: #{rails_load_error.class.name}: #{rails_load_error.message}"
|
50
141
|
end
|
51
142
|
|
52
|
-
|
53
|
-
|
143
|
+
server = RailsActiveMcp::Sdk::Server.new
|
144
|
+
server.run_stdio
|
54
145
|
rescue Interrupt
|
146
|
+
warn "[#{Time.now}] [RAILS-MCP] INFO: Server interrupted by user" if should_redirect
|
55
147
|
exit(0)
|
148
|
+
rescue LoadError => e
|
149
|
+
warn "[#{Time.now}] [RAILS-MCP] FATAL: MCP SDK not available: #{e.message}"
|
150
|
+
warn "[#{Time.now}] [RAILS-MCP] FATAL: Please install the MCP gem: gem install mcp"
|
151
|
+
exit(1)
|
152
|
+
rescue StandardError => e
|
153
|
+
warn "[#{Time.now}] [RAILS-MCP] FATAL: Server startup failed: #{e.message}"
|
154
|
+
warn "[#{Time.now}] [RAILS-MCP] FATAL: #{e.backtrace.join("\n")}" if ENV['RAILS_MCP_DEBUG']
|
155
|
+
exit(1)
|
56
156
|
end
|
57
157
|
|
58
158
|
when 'http'
|
59
|
-
|
60
|
-
puts
|
61
|
-
puts '
|
159
|
+
puts 'Error: HTTP transport is no longer supported in v2.0.0'
|
160
|
+
puts 'Please use stdio mode for MCP integration: rails-active-mcp-server stdio'
|
161
|
+
puts ''
|
162
|
+
puts 'For more information, see the migration guide in the documentation.'
|
163
|
+
exit(1)
|
62
164
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
165
|
+
when '--help', '-h'
|
166
|
+
puts 'Rails Active MCP Server'
|
167
|
+
puts "Version: #{RailsActiveMcp::VERSION}"
|
168
|
+
puts ''
|
169
|
+
puts 'Usage: rails-active-mcp-server [stdio] [options]'
|
170
|
+
puts ' stdio: For MCP integration (default)'
|
171
|
+
puts ''
|
172
|
+
puts 'Options:'
|
173
|
+
puts ' --help, -h Show this help message'
|
174
|
+
puts ''
|
175
|
+
puts 'Environment variables:'
|
176
|
+
puts ' RAILS_MCP_DEBUG=1 Enable debug logging and disable output redirection'
|
177
|
+
puts ''
|
178
|
+
puts 'Examples:'
|
179
|
+
puts ' rails-active-mcp-server stdio # Start in stdio mode'
|
180
|
+
puts ' RAILS_MCP_DEBUG=1 rails-active-mcp-server # Start with debug logging'
|
181
|
+
puts ''
|
182
|
+
puts 'Note: HTTP transport was removed in v2.0.0. Use stdio mode for MCP integration.'
|
183
|
+
exit(0)
|
80
184
|
|
81
185
|
else
|
82
|
-
puts 'Usage: rails-active-mcp-server [stdio
|
83
|
-
puts ' stdio: For
|
84
|
-
puts '
|
186
|
+
puts 'Usage: rails-active-mcp-server [stdio] [options]'
|
187
|
+
puts ' stdio: For MCP integration (default)'
|
188
|
+
puts ''
|
189
|
+
puts 'Options:'
|
190
|
+
puts ' --help, -h Show this help message'
|
191
|
+
puts ''
|
192
|
+
puts 'Environment variables:'
|
193
|
+
puts ' RAILS_MCP_DEBUG=1 Enable debug logging and disable output redirection'
|
194
|
+
puts ''
|
195
|
+
puts 'Note: HTTP transport was removed in v2.0.0. Use stdio mode for MCP integration.'
|
85
196
|
exit(1)
|
86
197
|
end
|
@@ -11,8 +11,81 @@ module RailsActiveMcp
|
|
11
11
|
template 'initializer.rb', 'config/initializers/rails_active_mcp.rb'
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
|
14
|
+
def create_binstub
|
15
|
+
# Create binstub for easy server execution
|
16
|
+
create_file 'bin/rails-active-mcp-server', <<~RUBY
|
17
|
+
#!/usr/bin/env ruby
|
18
|
+
|
19
|
+
# Binstub for Rails Active MCP Server
|
20
|
+
# This ensures the server runs within the Rails project context
|
21
|
+
|
22
|
+
require 'bundler/setup'
|
23
|
+
|
24
|
+
# Set Rails environment
|
25
|
+
ENV['RAILS_ENV'] ||= 'development'
|
26
|
+
|
27
|
+
# Load Rails application first
|
28
|
+
require_relative '../config/environment'
|
29
|
+
|
30
|
+
# Now start the MCP server using the SDK implementation
|
31
|
+
require 'rails_active_mcp/sdk/server'
|
32
|
+
|
33
|
+
begin
|
34
|
+
server = RailsActiveMcp::SDK::Server.new
|
35
|
+
server.run
|
36
|
+
rescue StandardError => e
|
37
|
+
warn "Error starting Rails Active MCP server: \#{e.message}"
|
38
|
+
warn e.backtrace if ENV['RAILS_MCP_DEBUG'] == '1'
|
39
|
+
exit 1
|
40
|
+
end
|
41
|
+
RUBY
|
42
|
+
|
43
|
+
chmod 'bin/rails-active-mcp-server', 0o755
|
44
|
+
say 'Created Rails binstub at bin/rails-active-mcp-server', :green
|
45
|
+
|
46
|
+
# Create environment-aware wrapper for Claude Desktop compatibility
|
47
|
+
ruby_path = `which ruby`.strip
|
48
|
+
|
49
|
+
create_file 'bin/rails-active-mcp-wrapper', <<~BASH
|
50
|
+
#!/usr/bin/env bash
|
51
|
+
|
52
|
+
# Rails Active MCP Wrapper Script
|
53
|
+
# Ensures correct Ruby environment for Claude Desktop execution
|
54
|
+
|
55
|
+
# Fix Claude Desktop environment isolation issues
|
56
|
+
export HOME="${HOME:-#{ENV['HOME']}}"
|
57
|
+
export USER="${USER:-$(whoami)}"
|
58
|
+
|
59
|
+
# Strategy 1: Use absolute Ruby path (most reliable)
|
60
|
+
RUBY_PATH="#{ruby_path}"
|
61
|
+
|
62
|
+
# Strategy 2: Try /usr/local/bin/ruby symlink as fallback
|
63
|
+
if [ ! -x "$RUBY_PATH" ]; then
|
64
|
+
RUBY_PATH="/usr/local/bin/ruby"
|
65
|
+
fi
|
66
|
+
|
67
|
+
# Strategy 3: Setup environment and use PATH resolution as last resort
|
68
|
+
if [ ! -x "$RUBY_PATH" ]; then
|
69
|
+
# Set up asdf environment if available
|
70
|
+
export ASDF_DIR="$HOME/.asdf"
|
71
|
+
if [ -f "$ASDF_DIR/asdf.sh" ]; then
|
72
|
+
source "$ASDF_DIR/asdf.sh"
|
73
|
+
fi
|
74
|
+
#{' '}
|
75
|
+
# Add version manager paths
|
76
|
+
export PATH="$HOME/.asdf/shims:$HOME/.rbenv/shims:$HOME/.rvm/bin:$PATH"
|
77
|
+
RUBY_PATH="ruby"
|
78
|
+
fi
|
79
|
+
|
80
|
+
# Change to the Rails project directory
|
81
|
+
cd "$(dirname "$0")/.."
|
82
|
+
|
83
|
+
# Execute with the determined Ruby path
|
84
|
+
exec "$RUBY_PATH" bin/rails-active-mcp-server "$@"
|
85
|
+
BASH
|
86
|
+
|
87
|
+
chmod 'bin/rails-active-mcp-wrapper', 0o755
|
88
|
+
say 'Created environment wrapper at bin/rails-active-mcp-wrapper', :green
|
16
89
|
end
|
17
90
|
|
18
91
|
def create_mcp_config
|
@@ -23,6 +96,53 @@ module RailsActiveMcp
|
|
23
96
|
readme 'README.md' if behavior == :invoke
|
24
97
|
end
|
25
98
|
|
99
|
+
def show_post_install_instructions
|
100
|
+
return unless behavior == :invoke
|
101
|
+
|
102
|
+
say "\n" + '=' * 50, :green
|
103
|
+
say 'Rails Active MCP Installation Complete!', :green
|
104
|
+
say '=' * 50, :green
|
105
|
+
say "\nFor Claude Desktop configuration:", :green
|
106
|
+
say 'Add this to your claude_desktop_config.json:', :yellow
|
107
|
+
say '', :green
|
108
|
+
say '{', :cyan
|
109
|
+
say ' "mcpServers": {', :cyan
|
110
|
+
say ' "rails-active-mcp": {', :cyan
|
111
|
+
say " \"command\": \"#{Rails.root}/bin/rails-active-mcp-wrapper\",", :cyan
|
112
|
+
say " \"cwd\": \"#{Rails.root}\",", :cyan
|
113
|
+
say ' "env": {', :cyan
|
114
|
+
say ' "RAILS_ENV": "development",', :cyan
|
115
|
+
say " \"HOME\": \"#{ENV['HOME']}\"", :cyan
|
116
|
+
say ' }', :cyan
|
117
|
+
say ' }', :cyan
|
118
|
+
say ' }', :cyan
|
119
|
+
say '}', :cyan
|
120
|
+
say '', :green
|
121
|
+
say "\nAvailable Tools in Claude Desktop:", :green
|
122
|
+
say '- console_execute: Execute Ruby code with safety checks', :yellow
|
123
|
+
say '- model_info: Get detailed information about Rails models', :yellow
|
124
|
+
say '- safe_query: Execute safe read-only database queries', :yellow
|
125
|
+
say '- dry_run: Analyze Ruby code for safety without execution', :yellow
|
126
|
+
say '', :green
|
127
|
+
say "\nWhy use the wrapper?", :green
|
128
|
+
say '- Handles Ruby version manager environments (asdf, rbenv, etc.)', :yellow
|
129
|
+
say '- Prevents "bundler version" and "Ruby version" conflicts', :yellow
|
130
|
+
say '- Works reliably across different development setups', :yellow
|
131
|
+
say "\nAlternative (if wrapper doesn't work):", :green
|
132
|
+
say 'Use bin/rails-active-mcp-server instead of the wrapper', :yellow
|
133
|
+
say "\nTesting:", :green
|
134
|
+
say '1. Test manually: bin/rails-active-mcp-wrapper', :yellow
|
135
|
+
say '2. Should output JSON responses (not plain text)', :yellow
|
136
|
+
say '3. Restart Claude Desktop after config changes', :yellow
|
137
|
+
say "\nTroubleshooting:", :green
|
138
|
+
say '- Set RAILS_MCP_DEBUG=1 for verbose logging', :yellow
|
139
|
+
say '- Check README.md for more configuration options', :yellow
|
140
|
+
say "\nFor Ruby version manager users (asdf/rbenv/RVM):", :green
|
141
|
+
say 'If you encounter "bundler version" errors, create a system symlink:', :yellow
|
142
|
+
say "sudo ln -sf #{`which ruby`.strip} /usr/local/bin/ruby", :cyan
|
143
|
+
say '=' * 50, :green
|
144
|
+
end
|
145
|
+
|
26
146
|
private
|
27
147
|
|
28
148
|
def readme(path)
|
@@ -30,7 +150,7 @@ module RailsActiveMcp
|
|
30
150
|
if File.exist?(readme_path)
|
31
151
|
say IO.read(readme_path), :green
|
32
152
|
else
|
33
|
-
say "README file not found at #{readme_path}", :
|
153
|
+
say "README file not found at #{readme_path}", :green
|
34
154
|
end
|
35
155
|
rescue StandardError => e
|
36
156
|
say "Error reading README: #{e.message}", :red
|
@@ -1,148 +1,54 @@
|
|
1
1
|
================================================================================
|
2
|
-
Rails Active MCP
|
2
|
+
Rails Active MCP Installation Complete!
|
3
3
|
================================================================================
|
4
4
|
|
5
|
-
|
6
|
-
- Initializer created at: config/initializers/rails_active_mcp.rb
|
7
|
-
- Custom MCP server mounted at: /mcp
|
8
|
-
- MCP server configuration: mcp.ru
|
9
|
-
- Audit log will be created at: log/rails_active_mcp.log
|
5
|
+
🎉 Rails Active MCP v2.0 with Official MCP Ruby SDK has been installed!
|
10
6
|
|
11
|
-
|
7
|
+
📁 Files Created:
|
8
|
+
- config/initializers/rails_active_mcp.rb (Configuration)
|
9
|
+
- bin/rails-active-mcp-server (Main server executable)
|
10
|
+
- bin/rails-active-mcp-wrapper (Environment wrapper for Claude Desktop)
|
11
|
+
- mcp.ru (Rack configuration file)
|
12
12
|
|
13
|
-
|
13
|
+
🛠️ Available MCP Tools:
|
14
|
+
- console_execute: Execute Ruby code with safety checks
|
15
|
+
- model_info: Get detailed information about Rails models
|
16
|
+
- safe_query: Execute safe read-only database queries
|
17
|
+
- dry_run: Analyze Ruby code for safety without execution
|
14
18
|
|
15
|
-
|
16
|
-
config.server_mode = :stdio # For Claude Desktop (default)
|
17
|
-
config.server_mode = :http # For HTTP-based integrations
|
18
|
-
config.server_host = 'localhost'
|
19
|
-
config.server_port = 3001
|
19
|
+
🚀 Quick Start:
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
$ bundle exec rails-active-mcp-server
|
24
|
-
|
25
|
-
Option B: Override mode via command line
|
26
|
-
$ bundle exec rails-active-mcp-server stdio # Force stdio mode
|
27
|
-
$ bundle exec rails-active-mcp-server http # Force HTTP mode
|
28
|
-
|
29
|
-
Option C: Rails-mounted server (HTTP)
|
30
|
-
$ rails server
|
31
|
-
|
32
|
-
Option D: Using rackup
|
33
|
-
$ rackup mcp.ru -p 3001
|
34
|
-
|
35
|
-
4. For Claude Desktop integration, add this to your Claude Desktop configuration:
|
36
|
-
|
37
|
-
Location: ~/.config/claude-desktop/claude_desktop_config.json (Linux/macOS)
|
38
|
-
Location: %APPDATA%\Claude\claude_desktop_config.json (Windows)
|
21
|
+
1. Test the server:
|
22
|
+
$ ./bin/rails-active-mcp-server
|
39
23
|
|
24
|
+
2. For Claude Desktop, add to claude_desktop_config.json:
|
40
25
|
{
|
41
26
|
"mcpServers": {
|
42
27
|
"rails-active-mcp": {
|
43
|
-
"command": "
|
44
|
-
"
|
45
|
-
"
|
28
|
+
"command": "/path/to/your/project/bin/rails-active-mcp-wrapper",
|
29
|
+
"cwd": "/path/to/your/project",
|
30
|
+
"env": {
|
31
|
+
"RAILS_ENV": "development",
|
32
|
+
"HOME": "/Users/your-username"
|
33
|
+
}
|
46
34
|
}
|
47
35
|
}
|
48
36
|
}
|
49
37
|
|
50
|
-
|
51
|
-
|
52
|
-
{
|
53
|
-
"mcpServers": {
|
54
|
-
"rails-active-mcp": {
|
55
|
-
"command": "rails-active-mcp-server",
|
56
|
-
"args": ["stdio"],
|
57
|
-
"cwd": "/path/to/your/rails/project"
|
58
|
-
}
|
59
|
-
}
|
60
|
-
}
|
61
|
-
|
62
|
-
5. For other MCP clients (HTTP-based), add this to your MCP configuration:
|
63
|
-
{
|
64
|
-
"mcpServers": {
|
65
|
-
"rails-console": {
|
66
|
-
"command": "curl",
|
67
|
-
"args": ["-X", "POST", "-H", "Content-Type: application/json", "-d", "@-", "http://localhost:3000/mcp"]
|
68
|
-
}
|
69
|
-
}
|
70
|
-
}
|
71
|
-
|
72
|
-
6. Test the installation:
|
73
|
-
$ rails console
|
74
|
-
> RailsActiveMcp.safe?("User.count")
|
75
|
-
> RailsActiveMcp.execute("User.count")
|
76
|
-
|
77
|
-
Built-in Tools Available in Claude:
|
78
|
-
- rails_console_execute: Execute Ruby code in Rails console with safety checks
|
79
|
-
- rails_model_info: Get detailed information about Rails models
|
80
|
-
- rails_safe_query: Execute safe read-only database queries
|
81
|
-
- rails_dry_run: Analyze Ruby code for safety without execution
|
82
|
-
|
83
|
-
Extend with custom tools by modifying the MCP server implementation.
|
84
|
-
|
85
|
-
Security Notes:
|
86
|
-
- Production mode enables strict safety by default
|
87
|
-
- All executions are logged to the audit file
|
88
|
-
- Dangerous operations are blocked in safe mode
|
89
|
-
- Review the safety patterns in the configuration
|
90
|
-
|
91
|
-
Transport Modes:
|
92
|
-
- stdio: For Claude Desktop and compatible MCP clients (recommended)
|
93
|
-
- http: For HTTP-based integrations and web applications
|
94
|
-
|
95
|
-
Configuration Examples:
|
96
|
-
|
97
|
-
For Claude Desktop (default):
|
98
|
-
config.server_mode = :stdio
|
99
|
-
|
100
|
-
For HTTP web integrations:
|
101
|
-
config.server_mode = :http
|
102
|
-
config.server_host = 'localhost'
|
103
|
-
config.server_port = 3001
|
104
|
-
|
105
|
-
For Docker/remote access:
|
106
|
-
config.http_mode!(host: '0.0.0.0', port: 8080)
|
107
|
-
|
108
|
-
For development with multiple transport modes:
|
109
|
-
if Rails.env.development?
|
110
|
-
config.stdio_mode! # Claude Desktop
|
111
|
-
else
|
112
|
-
config.http_mode!(host: '0.0.0.0', port: 3001) # Production HTTP
|
113
|
-
end
|
114
|
-
|
115
|
-
Custom MCP Server Benefits:
|
116
|
-
- No external dependencies
|
117
|
-
- Full control over implementation
|
118
|
-
- Simplified deployment
|
119
|
-
- Enhanced security
|
120
|
-
- Works with Claude Desktop
|
121
|
-
|
122
|
-
Debugging and Troubleshooting:
|
123
|
-
|
124
|
-
For interactive debugging, use the MCP Inspector:
|
125
|
-
$ bin/debug-mcp-server --mode inspector
|
126
|
-
|
127
|
-
This will:
|
128
|
-
- Launch the MCP Inspector connected to your server
|
129
|
-
- Allow interactive testing of all tools
|
130
|
-
- Show real-time debug output and logs
|
131
|
-
|
132
|
-
Debug logging:
|
133
|
-
$ RAILS_MCP_DEBUG=1 bundle exec rails-active-mcp-server stdio
|
38
|
+
3. Restart Claude Desktop and start using the tools!
|
134
39
|
|
135
|
-
|
136
|
-
|
137
|
-
|
40
|
+
⚙️ Configuration:
|
41
|
+
Edit config/initializers/rails_active_mcp.rb to customize:
|
42
|
+
- allowed_commands: Shell commands that can be executed
|
43
|
+
- command_timeout: Execution timeout in seconds
|
44
|
+
- enable_logging: Enable/disable logging
|
45
|
+
- log_level: Logging verbosity (:debug, :info, :warn, :error)
|
138
46
|
|
139
|
-
|
140
|
-
-
|
141
|
-
-
|
142
|
-
-
|
143
|
-
- Make sure the cwd path in Claude Desktop config is correct
|
144
|
-
- Enable debug logging with RAILS_MCP_DEBUG=1 for detailed output
|
47
|
+
🔧 Troubleshooting:
|
48
|
+
- Use the wrapper script to avoid Ruby version manager conflicts
|
49
|
+
- Set RAILS_MCP_DEBUG=1 for verbose logging
|
50
|
+
- Ensure Claude Desktop has correct paths and environment variables
|
145
51
|
|
146
|
-
|
52
|
+
📚 Documentation: https://github.com/goodpie/rails-active-mcp
|
147
53
|
|
148
54
|
================================================================================
|
@@ -1,43 +1,42 @@
|
|
1
1
|
require 'rails_active_mcp'
|
2
2
|
|
3
3
|
RailsActiveMcp.configure do |config|
|
4
|
-
#
|
5
|
-
config.
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
config.
|
18
|
-
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
# Environment-specific settings
|
29
|
-
case Rails.env
|
30
|
-
when 'production'
|
31
|
-
config.production_mode! # Very strict settings
|
32
|
-
when 'development'
|
33
|
-
config.permissive_mode! # More relaxed for development
|
34
|
-
when 'test'
|
35
|
-
config.strict_mode! # Safe for testing
|
4
|
+
# Core configuration options
|
5
|
+
config.allowed_commands = %w[
|
6
|
+
ls pwd cat head tail grep find wc
|
7
|
+
rails console rails runner
|
8
|
+
bundle exec rspec bundle exec test
|
9
|
+
git status git log git diff
|
10
|
+
]
|
11
|
+
|
12
|
+
# Execution timeout in seconds
|
13
|
+
config.command_timeout = 30
|
14
|
+
|
15
|
+
# Logging configuration
|
16
|
+
config.enable_logging = true
|
17
|
+
config.log_level = :info # :debug, :info, :warn, :error
|
18
|
+
|
19
|
+
# Environment-specific adjustments
|
20
|
+
if Rails.env.production?
|
21
|
+
# More restrictive settings for production
|
22
|
+
config.log_level = :warn
|
23
|
+
config.command_timeout = 15
|
24
|
+
elsif Rails.env.development?
|
25
|
+
# More permissive settings for development
|
26
|
+
config.log_level = :debug
|
27
|
+
config.command_timeout = 60
|
36
28
|
end
|
37
|
-
|
38
|
-
# Add custom safety patterns
|
39
|
-
# config.add_safety_pattern(/CustomDangerousMethod/, "Custom dangerous operation")
|
40
|
-
|
41
|
-
# Operations that require manual confirmation
|
42
|
-
config.require_confirmation_for = %i[delete destroy update_all delete_all]
|
43
29
|
end
|
30
|
+
|
31
|
+
# Rails Active MCP is now ready!
|
32
|
+
#
|
33
|
+
# Available MCP Tools:
|
34
|
+
# - console_execute: Execute Ruby code with safety checks
|
35
|
+
# - model_info: Get detailed information about Rails models
|
36
|
+
# - safe_query: Execute safe read-only database queries
|
37
|
+
# - dry_run: Analyze Ruby code for safety without execution
|
38
|
+
#
|
39
|
+
# To start the server:
|
40
|
+
# bin/rails-active-mcp-server
|
41
|
+
#
|
42
|
+
# For Claude Desktop integration, see the post-install instructions.
|