rails-active-mcp 0.1.6 → 0.1.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/app/controllers/rails_active_mcp/mcp_controller.rb +80 -0
- data/claude_desktop_config.json +12 -0
- data/docs/DEBUGGING.md +35 -3
- data/docs/GENERATOR_TESTING.md +121 -0
- data/exe/rails-active-mcp-server +54 -20
- data/lib/generators/rails_active_mcp/install/install_generator.rb +142 -2
- data/lib/generators/rails_active_mcp/install/templates/README.md +48 -8
- data/lib/rails_active_mcp/console_executor.rb +192 -78
- data/lib/rails_active_mcp/engine.rb +16 -0
- data/lib/rails_active_mcp/mcp_server.rb +36 -27
- data/lib/rails_active_mcp/railtie.rb +25 -3
- data/lib/rails_active_mcp/stdio_server.rb +111 -61
- data/lib/rails_active_mcp/version.rb +1 -1
- data/lib/rails_active_mcp.rb +7 -2
- data/rails_active_mcp.gemspec +5 -4
- metadata +27 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4af3c8128e9aa1ec5387c9c8ea90ff709e81287e8f9026b3a6ac1930e0f62204
|
4
|
+
data.tar.gz: 257ab1dd963dd7c377bc69f4a2a934d80eaa21e22e43567d551d729612b12712
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a30335d0e827dfaad9a4cfda26582ecd8c79cf0c4aab1fc9695df5e46145da4009d5228211a5cd26e4cca25f9417a9420793a10c5224068bac0297a69e0980ea
|
7
|
+
data.tar.gz: b73993876ec57ab0ce758ed79aa50b1e0c71f3b12963c39a4170de8a5e80eb3f2f0ccd6a17d88c36e07d71badcc652ddcc373fbb1cdeaabedd0d45d300cd047b
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsActiveMcp
|
4
|
+
class McpController < ApplicationController
|
5
|
+
protect_from_forgery with: :null_session
|
6
|
+
before_action :check_enabled
|
7
|
+
before_action :set_cors_headers
|
8
|
+
|
9
|
+
def handle
|
10
|
+
return head :method_not_allowed unless request.post?
|
11
|
+
return head :bad_request unless json_request?
|
12
|
+
|
13
|
+
begin
|
14
|
+
body = request.body.read
|
15
|
+
data = JSON.parse(body)
|
16
|
+
|
17
|
+
mcp_server = RailsActiveMcp::McpServer.new
|
18
|
+
response_data = mcp_server.handle_jsonrpc_request(data)
|
19
|
+
|
20
|
+
render json: response_data
|
21
|
+
rescue JSON::ParserError
|
22
|
+
render json: { error: 'Invalid JSON' }, status: :bad_request
|
23
|
+
rescue StandardError => e
|
24
|
+
RailsActiveMcp.logger.error "MCP Controller Error: #{e.message}"
|
25
|
+
render json: { error: 'Internal Server Error' }, status: :internal_server_error
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def sse
|
30
|
+
response.headers['Content-Type'] = 'text/event-stream'
|
31
|
+
response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
|
32
|
+
response.headers['Connection'] = 'keep-alive'
|
33
|
+
response.headers['X-Accel-Buffering'] = 'no'
|
34
|
+
|
35
|
+
# Send initial connection established event
|
36
|
+
render plain: ": SSE connection established\n\nevent: endpoint\ndata: #{request.base_url}#{rails_active_mcp.root_path}messages\n\nretry: 100\n\n"
|
37
|
+
end
|
38
|
+
|
39
|
+
def health
|
40
|
+
status = RailsActiveMcp.config.enabled ? 'healthy' : 'disabled'
|
41
|
+
render json: {
|
42
|
+
status: status,
|
43
|
+
version: RailsActiveMcp::VERSION,
|
44
|
+
timestamp: Time.current.iso8601
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def info
|
49
|
+
render json: {
|
50
|
+
name: 'Rails Active MCP',
|
51
|
+
version: RailsActiveMcp::VERSION,
|
52
|
+
description: 'Rails Console access via Model Context Protocol (MCP)',
|
53
|
+
endpoints: {
|
54
|
+
mcp: rails_active_mcp.root_path,
|
55
|
+
health: rails_active_mcp.root_path + 'health'
|
56
|
+
},
|
57
|
+
enabled: RailsActiveMcp.config.enabled
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def check_enabled
|
64
|
+
return if RailsActiveMcp.config.enabled
|
65
|
+
|
66
|
+
render json: { error: 'Rails Active MCP is disabled' }, status: :service_unavailable
|
67
|
+
end
|
68
|
+
|
69
|
+
def json_request?
|
70
|
+
request.content_type&.include?('application/json')
|
71
|
+
end
|
72
|
+
|
73
|
+
def set_cors_headers
|
74
|
+
response.headers['Access-Control-Allow-Origin'] = '*'
|
75
|
+
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
|
76
|
+
response.headers['Access-Control-Allow-Headers'] = 'Content-Type'
|
77
|
+
response.headers['Access-Control-Max-Age'] = '86400'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/docs/DEBUGGING.md
CHANGED
@@ -126,7 +126,7 @@ The logs show:
|
|
126
126
|
"mcpServers": {
|
127
127
|
"rails-active-mcp": {
|
128
128
|
"command": "bundle",
|
129
|
-
"args": ["exec", "rails-active-mcp-server"
|
129
|
+
"args": ["exec", "rails-active-mcp-server"],
|
130
130
|
"cwd": "/path/to/rails/project",
|
131
131
|
"env": {
|
132
132
|
"RAILS_ENV": "development",
|
@@ -137,7 +137,39 @@ The logs show:
|
|
137
137
|
}
|
138
138
|
```
|
139
139
|
|
140
|
-
|
140
|
+
**Note**: The server will use the mode configured in your Rails initializer (`:stdio` by default). You can override this by adding the mode as an argument: `["exec", "rails-active-mcp-server", "stdio"]`
|
141
|
+
|
142
|
+
### 3. Server Mode Configuration
|
143
|
+
|
144
|
+
**Problem**: Want to change the default server mode.
|
145
|
+
|
146
|
+
**Solution**: Configure server mode in your Rails initializer:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
# config/initializers/rails_active_mcp.rb
|
150
|
+
RailsActiveMcp.configure do |config|
|
151
|
+
# For Claude Desktop (default)
|
152
|
+
config.server_mode = :stdio
|
153
|
+
|
154
|
+
# For HTTP-based integrations
|
155
|
+
config.http_mode!(host: '0.0.0.0', port: 8080)
|
156
|
+
|
157
|
+
# Or just set stdio mode
|
158
|
+
config.stdio_mode!
|
159
|
+
end
|
160
|
+
```
|
161
|
+
|
162
|
+
**Command line override**:
|
163
|
+
```bash
|
164
|
+
# Use configured mode
|
165
|
+
bundle exec rails-active-mcp-server
|
166
|
+
|
167
|
+
# Force specific mode
|
168
|
+
bundle exec rails-active-mcp-server stdio
|
169
|
+
bundle exec rails-active-mcp-server http --port 8080
|
170
|
+
```
|
171
|
+
|
172
|
+
### 4. Server Initialization Problems
|
141
173
|
|
142
174
|
**Common initialization issues:**
|
143
175
|
|
@@ -162,7 +194,7 @@ The logs show:
|
|
162
194
|
chmod +x exe/rails-active-mcp-server
|
163
195
|
```
|
164
196
|
|
165
|
-
###
|
197
|
+
### 5. Connection Problems
|
166
198
|
|
167
199
|
**Problem**: Claude Desktop can't connect to server.
|
168
200
|
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# Testing the Rails Active MCP Generator
|
2
|
+
|
3
|
+
This guide explains how to test that your Rails Active MCP generator is working correctly.
|
4
|
+
|
5
|
+
## Quick Test in a New Rails App
|
6
|
+
|
7
|
+
1. **Create a test Rails app:**
|
8
|
+
```bash
|
9
|
+
rails new test_mcp_app
|
10
|
+
cd test_mcp_app
|
11
|
+
```
|
12
|
+
|
13
|
+
2. **Add your gem to the Gemfile:**
|
14
|
+
```ruby
|
15
|
+
# Add to Gemfile
|
16
|
+
gem 'rails-active-mcp', path: '/path/to/your/gem'
|
17
|
+
# OR if published:
|
18
|
+
gem 'rails-active-mcp'
|
19
|
+
```
|
20
|
+
|
21
|
+
3. **Bundle install:**
|
22
|
+
```bash
|
23
|
+
bundle install
|
24
|
+
```
|
25
|
+
|
26
|
+
4. **Check if the generator is available:**
|
27
|
+
```bash
|
28
|
+
rails generate --help
|
29
|
+
```
|
30
|
+
You should see `rails_active_mcp:install` in the list.
|
31
|
+
|
32
|
+
5. **Run the generator:**
|
33
|
+
```bash
|
34
|
+
rails generate rails_active_mcp:install
|
35
|
+
```
|
36
|
+
|
37
|
+
6. **Verify generated files:**
|
38
|
+
- `config/initializers/rails_active_mcp.rb` should exist
|
39
|
+
- `mcp.ru` should exist
|
40
|
+
- `config/routes.rb` should have the mount line added
|
41
|
+
|
42
|
+
## What the Generator Should Create
|
43
|
+
|
44
|
+
### Initializer File
|
45
|
+
Location: `config/initializers/rails_active_mcp.rb`
|
46
|
+
|
47
|
+
Should contain:
|
48
|
+
- Configuration block with `RailsActiveMcp.configure`
|
49
|
+
- Environment-specific settings
|
50
|
+
- Safety and logging configuration
|
51
|
+
|
52
|
+
### MCP Server Configuration
|
53
|
+
Location: `mcp.ru`
|
54
|
+
|
55
|
+
Should contain:
|
56
|
+
- Rack configuration for standalone MCP server
|
57
|
+
- Proper requires and server initialization
|
58
|
+
|
59
|
+
### Route Addition
|
60
|
+
In `config/routes.rb`:
|
61
|
+
- Should add: `mount RailsActiveMcp::McpServer.new, at: '/mcp'`
|
62
|
+
|
63
|
+
## Generator Commands to Test
|
64
|
+
|
65
|
+
```bash
|
66
|
+
# See generator help
|
67
|
+
rails generate rails_active_mcp:install --help
|
68
|
+
|
69
|
+
# Run with verbose output
|
70
|
+
rails generate rails_active_mcp:install --verbose
|
71
|
+
|
72
|
+
# Skip files (for testing)
|
73
|
+
rails generate rails_active_mcp:install --skip-route
|
74
|
+
```
|
75
|
+
|
76
|
+
## Common Issues and Solutions
|
77
|
+
|
78
|
+
### Generator Not Found
|
79
|
+
If `rails generate rails_active_mcp:install` returns "Could not find generator", check:
|
80
|
+
|
81
|
+
1. **Gem is properly installed:** `bundle list | grep rails-active-mcp`
|
82
|
+
2. **Generator file exists:** Check `lib/generators/rails_active_mcp/install/install_generator.rb`
|
83
|
+
3. **Class name matches:** Ensure class is `RailsActiveMcp::Generators::InstallGenerator`
|
84
|
+
4. **Engine is loaded:** Check that the Engine is being required
|
85
|
+
|
86
|
+
### Files Not Generated
|
87
|
+
If files aren't created:
|
88
|
+
|
89
|
+
1. **Check permissions:** Ensure Rails can write to the directories
|
90
|
+
2. **Check templates:** Verify template files exist in `templates/` directory
|
91
|
+
3. **Check source_root:** Ensure `source_root` points to correct directory
|
92
|
+
|
93
|
+
### Route Not Added
|
94
|
+
If the route isn't added to `config/routes.rb`:
|
95
|
+
|
96
|
+
1. **Check routes.rb exists:** Generator requires existing routes file
|
97
|
+
2. **File permissions:** Ensure routes.rb is writable
|
98
|
+
|
99
|
+
## Running Tests
|
100
|
+
|
101
|
+
Run the generator specs:
|
102
|
+
```bash
|
103
|
+
bundle exec rspec spec/generators/
|
104
|
+
```
|
105
|
+
|
106
|
+
## Debugging Generator Issues
|
107
|
+
|
108
|
+
Add debugging to your generator:
|
109
|
+
```ruby
|
110
|
+
def create_initializer
|
111
|
+
say "Creating initializer at: #{destination_root}/config/initializers/rails_active_mcp.rb"
|
112
|
+
template 'initializer.rb', 'config/initializers/rails_active_mcp.rb'
|
113
|
+
say "Initializer created successfully", :green
|
114
|
+
end
|
115
|
+
```
|
116
|
+
|
117
|
+
Check Rails generator resolution:
|
118
|
+
```ruby
|
119
|
+
# In rails console
|
120
|
+
Rails::Generators.find_by_namespace("rails_active_mcp:install")
|
121
|
+
```
|
data/exe/rails-active-mcp-server
CHANGED
@@ -4,20 +4,52 @@
|
|
4
4
|
require 'rack'
|
5
5
|
require 'json'
|
6
6
|
require 'stringio'
|
7
|
+
|
8
|
+
# Suppress ALL output immediately when not in debug mode to prevent MCP JSON protocol interference
|
9
|
+
original_stdout = $stdout
|
10
|
+
original_stderr = $stderr
|
11
|
+
|
12
|
+
# Only suppress if we're likely running in stdio mode (for Claude) and not debugging
|
13
|
+
if ARGV.first == 'stdio' && !ENV['RAILS_MCP_DEBUG']
|
14
|
+
# Redirect to temporary StringIO until Rails loading is complete
|
15
|
+
$stdout = StringIO.new
|
16
|
+
$stderr = StringIO.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# Initialize Rails environment if available (from current working directory)
|
20
|
+
rails_loaded = false
|
21
|
+
if File.exist?('config/environment.rb')
|
22
|
+
begin
|
23
|
+
require './config/environment'
|
24
|
+
rails_loaded = true
|
25
|
+
rescue StandardError => e
|
26
|
+
# Rails loading failed, continue without it
|
27
|
+
# Only show warning in debug mode
|
28
|
+
warn "Warning: Failed to load Rails environment: #{e.message}" if ENV['RAILS_MCP_DEBUG']
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Restore stdout/stderr after Rails loading for non-debug stdio mode
|
33
|
+
if ARGV.first == 'stdio' && !ENV['RAILS_MCP_DEBUG']
|
34
|
+
$stdout = original_stdout
|
35
|
+
$stderr = original_stderr
|
36
|
+
end
|
37
|
+
|
38
|
+
# Now load the gem
|
7
39
|
require_relative '../lib/rails_active_mcp'
|
8
40
|
|
9
|
-
# Parse command line options with config defaults
|
10
|
-
default_mode = if defined?(RailsActiveMcp) && RailsActiveMcp.respond_to?(:config)
|
41
|
+
# Parse command line options with config defaults (only after Rails is loaded)
|
42
|
+
default_mode = if rails_loaded && defined?(RailsActiveMcp) && RailsActiveMcp.respond_to?(:config)
|
11
43
|
RailsActiveMcp.config.server_mode.to_s
|
12
44
|
else
|
13
45
|
'stdio'
|
14
46
|
end
|
15
|
-
default_port = if defined?(RailsActiveMcp) && RailsActiveMcp.respond_to?(:config)
|
47
|
+
default_port = if rails_loaded && defined?(RailsActiveMcp) && RailsActiveMcp.respond_to?(:config)
|
16
48
|
RailsActiveMcp.config.server_port
|
17
49
|
else
|
18
50
|
3001
|
19
51
|
end
|
20
|
-
default_host = if defined?(RailsActiveMcp) && RailsActiveMcp.respond_to?(:config)
|
52
|
+
default_host = if rails_loaded && defined?(RailsActiveMcp) && RailsActiveMcp.respond_to?(:config)
|
21
53
|
RailsActiveMcp.config.server_host
|
22
54
|
else
|
23
55
|
'localhost'
|
@@ -33,30 +65,29 @@ when 'stdio'
|
|
33
65
|
require_relative '../lib/rails_active_mcp/stdio_server'
|
34
66
|
|
35
67
|
begin
|
36
|
-
#
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
ensure
|
48
|
-
$stdout = original_stdout
|
49
|
-
end
|
68
|
+
# Final stderr redirection to prevent any remaining output from interfering with MCP JSON protocol
|
69
|
+
# This is critical because Claude Desktop expects ONLY JSON on stdout and ANY non-JSON breaks the protocol
|
70
|
+
unless ENV['RAILS_MCP_DEBUG']
|
71
|
+
# Create log directory if it doesn't exist
|
72
|
+
log_dir = File.join(Dir.pwd, 'log')
|
73
|
+
Dir.mkdir(log_dir) unless Dir.exist?(log_dir)
|
74
|
+
|
75
|
+
# Redirect stderr to log file
|
76
|
+
stderr_log = File.join(log_dir, 'rails_mcp_stderr.log')
|
77
|
+
$stderr.reopen(stderr_log, 'a')
|
78
|
+
$stderr.sync = true
|
50
79
|
end
|
51
80
|
|
52
81
|
stdio_server = RailsActiveMcp::StdioServer.new
|
53
|
-
stdio_server.
|
82
|
+
stdio_server.start
|
54
83
|
rescue Interrupt
|
55
84
|
exit(0)
|
56
85
|
end
|
57
86
|
|
58
87
|
when 'http'
|
59
88
|
# HTTP transport for other integrations
|
89
|
+
puts 'Warning: Rails environment not loaded. Some features may not work properly.' unless rails_loaded
|
90
|
+
|
60
91
|
puts "Starting Rails Active MCP Server on #{host}:#{port}"
|
61
92
|
puts 'Press Ctrl+C to stop'
|
62
93
|
|
@@ -81,6 +112,9 @@ when 'http'
|
|
81
112
|
else
|
82
113
|
puts 'Usage: rails-active-mcp-server [stdio|http] [--port PORT] [--host HOST]'
|
83
114
|
puts ' stdio: For Claude Desktop integration'
|
84
|
-
puts ' http: For HTTP-based integrations
|
115
|
+
puts ' http: For HTTP-based integrations'
|
116
|
+
puts ''
|
117
|
+
puts 'Environment variables:'
|
118
|
+
puts ' RAILS_MCP_DEBUG=1 Enable debug logging'
|
85
119
|
exit(1)
|
86
120
|
end
|
@@ -11,8 +11,106 @@ module RailsActiveMcp
|
|
11
11
|
template 'initializer.rb', 'config/initializers/rails_active_mcp.rb'
|
12
12
|
end
|
13
13
|
|
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
|
+
require 'stringio'
|
24
|
+
|
25
|
+
# Set Rails environment
|
26
|
+
ENV['RAILS_ENV'] ||= 'development'
|
27
|
+
|
28
|
+
# Suppress Rails loading output for MCP JSON protocol
|
29
|
+
unless ENV['RAILS_MCP_DEBUG'] == '1'
|
30
|
+
original_stdout = $stdout
|
31
|
+
original_stderr = $stderr
|
32
|
+
$stdout = StringIO.new
|
33
|
+
$stderr = StringIO.new
|
34
|
+
end
|
35
|
+
|
36
|
+
# Load Rails application
|
37
|
+
require_relative '../config/environment'
|
38
|
+
|
39
|
+
# Restore output streams
|
40
|
+
unless ENV['RAILS_MCP_DEBUG'] == '1'
|
41
|
+
$stdout = original_stdout
|
42
|
+
$stderr = original_stderr
|
43
|
+
end
|
44
|
+
|
45
|
+
# Now run the actual MCP server
|
46
|
+
load Gem.bin_path('rails_active_mcp', 'rails-active-mcp-server')
|
47
|
+
RUBY
|
48
|
+
|
49
|
+
chmod 'bin/rails-active-mcp-server', 0o755
|
50
|
+
say 'Created Rails binstub at bin/rails-active-mcp-server', :green
|
51
|
+
|
52
|
+
# Create environment-aware wrapper for Claude Desktop compatibility
|
53
|
+
ruby_path = `which ruby`.strip
|
54
|
+
|
55
|
+
create_file 'bin/rails-active-mcp-wrapper', <<~BASH
|
56
|
+
#!/usr/bin/env bash
|
57
|
+
|
58
|
+
# Rails Active MCP Wrapper Script
|
59
|
+
# Ensures correct Ruby environment for Claude Desktop execution
|
60
|
+
# Research-based solution for version manager compatibility
|
61
|
+
|
62
|
+
# Fix Claude Desktop environment isolation issues
|
63
|
+
export HOME="${HOME:-#{ENV['HOME']}}"
|
64
|
+
export USER="${USER:-$(whoami)}"
|
65
|
+
|
66
|
+
# Strategy 1: Use absolute Ruby path (most reliable)
|
67
|
+
RUBY_PATH="#{ruby_path}"
|
68
|
+
|
69
|
+
# Strategy 2: Try /usr/local/bin/ruby symlink as fallback
|
70
|
+
if [ ! -x "$RUBY_PATH" ]; then
|
71
|
+
RUBY_PATH="/usr/local/bin/ruby"
|
72
|
+
fi
|
73
|
+
|
74
|
+
# Strategy 3: Setup environment and use PATH resolution as last resort
|
75
|
+
if [ ! -x "$RUBY_PATH" ]; then
|
76
|
+
# Set up asdf environment if available
|
77
|
+
export ASDF_DIR="$HOME/.asdf"
|
78
|
+
if [ -f "$ASDF_DIR/asdf.sh" ]; then
|
79
|
+
source "$ASDF_DIR/asdf.sh"
|
80
|
+
fi
|
81
|
+
#{' '}
|
82
|
+
# Add version manager paths
|
83
|
+
export PATH="$HOME/.asdf/shims:$HOME/.rbenv/shims:$HOME/.rvm/bin:$PATH"
|
84
|
+
RUBY_PATH="ruby"
|
85
|
+
fi
|
86
|
+
|
87
|
+
# Change to the Rails project directory
|
88
|
+
cd "$(dirname "$0")/.."
|
89
|
+
|
90
|
+
# Execute with the determined Ruby path
|
91
|
+
exec "$RUBY_PATH" bin/rails-active-mcp-server "$@"
|
92
|
+
BASH
|
93
|
+
|
94
|
+
chmod 'bin/rails-active-mcp-wrapper', 0o755
|
95
|
+
say 'Created environment wrapper at bin/rails-active-mcp-wrapper', :green
|
96
|
+
end
|
97
|
+
|
14
98
|
def create_mcp_route
|
15
|
-
|
99
|
+
# Check if routes file exists and is writable
|
100
|
+
routes_file = 'config/routes.rb'
|
101
|
+
return unless File.exist?(routes_file)
|
102
|
+
|
103
|
+
# Read current routes to check for conflicts
|
104
|
+
routes_content = File.read(routes_file)
|
105
|
+
|
106
|
+
if routes_content.include?('/mcp')
|
107
|
+
say "Warning: Route '/mcp' already exists. Skipping route creation.", :yellow
|
108
|
+
say "Manual setup: Add 'mount RailsActiveMcp::Engine, at: \"/mcp\"' to your routes.rb", :yellow
|
109
|
+
else
|
110
|
+
# Use Engine mounting instead of direct server mounting
|
111
|
+
route "mount RailsActiveMcp::Engine, at: '/mcp'"
|
112
|
+
say "Added MCP route at '/mcp'. You can change this in config/routes.rb", :green
|
113
|
+
end
|
16
114
|
end
|
17
115
|
|
18
116
|
def create_mcp_config
|
@@ -23,6 +121,48 @@ module RailsActiveMcp
|
|
23
121
|
readme 'README.md' if behavior == :invoke
|
24
122
|
end
|
25
123
|
|
124
|
+
def show_post_install_instructions
|
125
|
+
return unless behavior == :invoke
|
126
|
+
|
127
|
+
say "\n" + '=' * 50, :green
|
128
|
+
say 'Rails Active MCP Installation Complete!', :green
|
129
|
+
say '=' * 50, :green
|
130
|
+
say "\nFor Claude Desktop configuration:", :green
|
131
|
+
say 'Add this to your claude_desktop_config.json:', :yellow
|
132
|
+
say '', :green
|
133
|
+
say '{', :cyan
|
134
|
+
say ' "mcpServers": {', :cyan
|
135
|
+
say ' "rails-active-mcp": {', :cyan
|
136
|
+
say " \"command\": \"#{Rails.root}/bin/rails-active-mcp-wrapper\",", :cyan
|
137
|
+
say ' "args": ["stdio"],', :cyan
|
138
|
+
say " \"cwd\": \"#{Rails.root}\",", :cyan
|
139
|
+
say ' "env": {', :cyan
|
140
|
+
say ' "RAILS_ENV": "development",', :cyan
|
141
|
+
say " \"HOME\": \"#{ENV['HOME']}\"", :cyan
|
142
|
+
say ' }', :cyan
|
143
|
+
say ' }', :cyan
|
144
|
+
say ' }', :cyan
|
145
|
+
say '}', :cyan
|
146
|
+
say '', :green
|
147
|
+
say "\nWhy use the wrapper?", :green
|
148
|
+
say '- Handles Ruby version manager environments (asdf, rbenv, etc.)', :yellow
|
149
|
+
say '- Prevents "bundler version" and "Ruby version" conflicts', :yellow
|
150
|
+
say '- Works reliably across different development setups', :yellow
|
151
|
+
say "\nAlternative (if wrapper doesn't work):", :green
|
152
|
+
say 'Use bin/rails-active-mcp-server instead of the wrapper', :yellow
|
153
|
+
say "\nTesting:", :green
|
154
|
+
say '1. Test manually: bin/rails-active-mcp-wrapper stdio', :yellow
|
155
|
+
say '2. Should output JSON (not plain text)', :yellow
|
156
|
+
say '3. Restart Claude Desktop after config changes', :yellow
|
157
|
+
say "\nTroubleshooting:", :green
|
158
|
+
say '- Set RAILS_MCP_DEBUG=1 for verbose logging', :yellow
|
159
|
+
say '- Check README.md for more configuration options', :yellow
|
160
|
+
say "\nFor Ruby version manager users (asdf/rbenv/RVM):", :green
|
161
|
+
say 'If you encounter "bundler version" errors, create a system symlink:', :yellow
|
162
|
+
say "sudo ln -sf #{`which ruby`.strip} /usr/local/bin/ruby", :cyan
|
163
|
+
say '=' * 50, :green
|
164
|
+
end
|
165
|
+
|
26
166
|
private
|
27
167
|
|
28
168
|
def readme(path)
|
@@ -30,7 +170,7 @@ module RailsActiveMcp
|
|
30
170
|
if File.exist?(readme_path)
|
31
171
|
say IO.read(readme_path), :green
|
32
172
|
else
|
33
|
-
say "README file not found at #{readme_path}", :
|
173
|
+
say "README file not found at #{readme_path}", :green
|
34
174
|
end
|
35
175
|
rescue StandardError => e
|
36
176
|
say "Error reading README: #{e.message}", :red
|
@@ -40,9 +40,13 @@ Next Steps:
|
|
40
40
|
{
|
41
41
|
"mcpServers": {
|
42
42
|
"rails-active-mcp": {
|
43
|
-
"command": "
|
44
|
-
"args": ["
|
45
|
-
"cwd": "
|
43
|
+
"command": "<%= Rails.root %>/bin/rails-active-mcp-wrapper",
|
44
|
+
"args": ["stdio"],
|
45
|
+
"cwd": "<%= Rails.root %>",
|
46
|
+
"env": {
|
47
|
+
"RAILS_ENV": "development",
|
48
|
+
"HOME": "/Users/your-username"
|
49
|
+
}
|
46
50
|
}
|
47
51
|
}
|
48
52
|
}
|
@@ -137,11 +141,47 @@ $ tail -f ~/Library/Logs/Claude/mcp*.log # macOS
|
|
137
141
|
$ tail -f ~/.config/claude-desktop/logs/*.log # Linux
|
138
142
|
|
139
143
|
Common issues:
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
144
|
+
|
145
|
+
1. Ruby Version Manager Conflicts (Most Common Issue):
|
146
|
+
If you see errors like "Could not find 'bundler' (X.X.X)" or "Your Ruby version is X.X.X, but your Gemfile specified Y.Y.Y":
|
147
|
+
|
148
|
+
This happens because Claude Desktop uses system Ruby instead of your project's Ruby version.
|
149
|
+
|
150
|
+
Solution A - Use the wrapper script (Recommended):
|
151
|
+
In claude_desktop_config.json, use:
|
152
|
+
"command": "<%= Rails.root %>/bin/rails-active-mcp-wrapper"
|
153
|
+
|
154
|
+
Solution B - Create system symlink:
|
155
|
+
$ sudo ln -sf $(which ruby) /usr/local/bin/ruby
|
156
|
+
|
157
|
+
Solution C - Use absolute Ruby path:
|
158
|
+
In claude_desktop_config.json, change "command" to your full Ruby path:
|
159
|
+
"command": "$(which ruby)"
|
160
|
+
"args": ["<%= Rails.root %>/bin/rails-active-mcp-server", "stdio"]
|
161
|
+
|
162
|
+
2. Environment Variable Issues:
|
163
|
+
If you see "error loading config: $HOME is not defined":
|
164
|
+
|
165
|
+
This happens because Claude Desktop doesn't inherit all environment variables.
|
166
|
+
|
167
|
+
Solution: Add HOME to your env section in claude_desktop_config.json:
|
168
|
+
"env": {
|
169
|
+
"RAILS_ENV": "development",
|
170
|
+
"HOME": "/Users/your-username"
|
171
|
+
}
|
172
|
+
|
173
|
+
3. General Environment Issues:
|
174
|
+
- Ensure your Rails environment loads properly in the project directory
|
175
|
+
- Check that the gem is properly installed and configured
|
176
|
+
- Verify the Rails application starts without errors
|
177
|
+
- Make sure the cwd path in Claude Desktop config is correct
|
178
|
+
|
179
|
+
4. Debug Steps:
|
180
|
+
- Test manually: $ ./bin/rails-active-mcp-wrapper stdio
|
181
|
+
- Should output JSON (not plain text)
|
182
|
+
- Enable debug logging with RAILS_MCP_DEBUG=1 for detailed output
|
183
|
+
- Check Claude logs: $ tail -f ~/Library/Logs/Claude/mcp*.log
|
184
|
+
- Test environment variables: $ echo $HOME (should show your home directory)
|
145
185
|
|
146
186
|
For more information: https://github.com/goodpie/rails-active-mcp
|
147
187
|
|