rails-active-mcp 0.1.7 → 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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +106 -279
  3. data/changelog.md +69 -0
  4. data/docs/DEBUGGING.md +5 -5
  5. data/docs/README.md +130 -142
  6. data/exe/rails-active-mcp-server +153 -76
  7. data/lib/generators/rails_active_mcp/install/install_generator.rb +19 -39
  8. data/lib/generators/rails_active_mcp/install/templates/README.md +30 -164
  9. data/lib/generators/rails_active_mcp/install/templates/initializer.rb +37 -38
  10. data/lib/generators/rails_active_mcp/install/templates/mcp.ru +7 -3
  11. data/lib/rails_active_mcp/configuration.rb +37 -98
  12. data/lib/rails_active_mcp/console_executor.rb +13 -3
  13. data/lib/rails_active_mcp/engine.rb +36 -24
  14. data/lib/rails_active_mcp/sdk/server.rb +183 -0
  15. data/lib/rails_active_mcp/sdk/tools/console_execute_tool.rb +103 -0
  16. data/lib/rails_active_mcp/sdk/tools/dry_run_tool.rb +73 -0
  17. data/lib/rails_active_mcp/sdk/tools/model_info_tool.rb +106 -0
  18. data/lib/rails_active_mcp/sdk/tools/safe_query_tool.rb +77 -0
  19. data/lib/rails_active_mcp/version.rb +1 -1
  20. data/lib/rails_active_mcp.rb +5 -11
  21. data/rails_active_mcp.gemspec +4 -1
  22. metadata +22 -11
  23. data/app/controllers/rails_active_mcp/mcp_controller.rb +0 -80
  24. data/lib/rails_active_mcp/mcp_server.rb +0 -383
  25. data/lib/rails_active_mcp/railtie.rb +0 -70
  26. data/lib/rails_active_mcp/stdio_server.rb +0 -517
  27. data/lib/rails_active_mcp/tools/console_execute_tool.rb +0 -61
  28. data/lib/rails_active_mcp/tools/dry_run_tool.rb +0 -41
  29. data/lib/rails_active_mcp/tools/model_info_tool.rb +0 -70
  30. data/lib/rails_active_mcp/tools/safe_query_tool.rb +0 -41
data/docs/README.md CHANGED
@@ -1,22 +1,20 @@
1
1
  # Rails Active MCP Documentation
2
2
 
3
3
  ## Introduction
4
- Rails Active MCP is a Ruby gem that integrates the Model Context Protocol (MCP) into Rails applications. It provides a secure, configurable, and extensible server for AI agents and developer tools to interact with your Rails app via a standardized protocol.
4
+ Rails Active MCP is a Ruby gem that integrates the Model Context Protocol (MCP) into Rails applications using the official MCP Ruby SDK. It provides a secure, configurable, and professional server for AI agents and developer tools to interact with your Rails app via the standardized MCP protocol.
5
5
 
6
6
  ## How It Works
7
- - **Custom MCP Server**: Implements the MCP protocol (JSON-RPC 2.0 over HTTP) as a Rack middleware, mountable in Rails or runnable standalone.
8
- - **Tooling**: Exposes a set of tools (e.g., safe console execution, model info, safe queries, code analysis) to MCP clients.
9
- - **Safety**: Advanced safety checks, read-only modes, and audit logging protect your application from dangerous operations.
10
- - **Integration**: Easily added to any Rails 7+ app via a generator, with configuration via an initializer.
7
+ - **Official MCP SDK**: Built on the official MCP Ruby SDK (`mcp` gem) for robust protocol handling
8
+ - **Professional Implementation**: Automatic instrumentation, timing, and error reporting
9
+ - **Tooling**: Exposes four powerful tools (console execution, model info, safe queries, code analysis) to MCP clients
10
+ - **Safety**: Advanced safety checks, read-only modes, and audit logging protect your application from dangerous operations
11
+ - **Integration**: Easily added to any Rails application via a generator, with simplified configuration
11
12
 
12
13
  ## MCP Protocol Overview
13
- - **MCP**: The Model Context Protocol is a standard for structured, secure, and auditable access to application internals for AI agents and developer tools.
14
- - **Supported Methods**:
15
- - `initialize`: Returns server capabilities and protocol version.
16
- - `tools/list`: Lists available tools and their schemas.
17
- - `tools/call`: Executes a tool with given arguments.
18
- - `resources/list` and `resources/read`: (Stubbed, for future resource access.)
19
- - **JSON-RPC 2.0**: All communication uses JSON-RPC 2.0 over HTTP POST.
14
+ - **MCP**: The Model Context Protocol is a standard for structured, secure, and auditable access to application internals for AI agents and developer tools
15
+ - **Official SDK**: Uses the official MCP Ruby SDK for protocol compliance and future-proof compatibility
16
+ - **STDIO Transport**: Perfect for Claude Desktop integration
17
+ - **JSON-RPC 2.0**: All communication uses JSON-RPC 2.0 with automatic protocol handling
20
18
 
21
19
  ## Installation & Setup
22
20
  1. Add to your Gemfile:
@@ -28,158 +26,148 @@ Rails Active MCP is a Ruby gem that integrates the Model Context Protocol (MCP)
28
26
  bundle install
29
27
  rails generate rails_active_mcp:install
30
28
  ```
31
- This creates an initializer, mounts the MCP server at `/mcp`, and sets up audit logging.
29
+ This creates an initializer and sets up the Rails integration.
32
30
  3. Start the server:
33
- - Rails: `rails server` (MCP at `/mcp`)
34
- - Standalone: `bundle exec rails-active-mcp-server`
35
- - Rack: `rackup mcp.ru -p 3001`
31
+ ```bash
32
+ bundle exec rails-active-mcp-server
33
+ ```
36
34
 
37
35
  ## Configuration
38
36
  Edit `config/initializers/rails_active_mcp.rb`:
39
- - Enable/disable the server
40
- - Safety mode (production = strict)
41
- - Allowed/blocked models
42
- - Enable/disable mutation tools
43
- - Audit log location
44
- - Environment presets: `production_mode!`, `strict_mode!`, `permissive_mode!`
45
37
 
46
- ## Available Tools
47
- - **rails_console_execute**: Execute Ruby code in Rails with safety checks
48
- - **rails_model_info**: Inspect model schema and associations
49
- - **rails_safe_query**: Run safe, read-only queries on models
50
- - **rails_dry_run**: Analyze code for safety without executing
38
+ ```ruby
39
+ RailsActiveMcp.configure do |config|
40
+ # Core configuration options
41
+ config.allowed_commands = %w[
42
+ ls pwd cat head tail grep find wc
43
+ rails console rails runner
44
+ bundle exec rspec bundle exec test
45
+ git status git log git diff
46
+ ]
47
+ config.command_timeout = 30
48
+ config.enable_logging = true
49
+ config.log_level = :info
50
+ end
51
+ ```
51
52
 
52
- Each tool is described in the MCP `tools/list` response and can be extended or customized.
53
+ ## Available Tools
53
54
 
54
- ## Security & Safety
55
- - **Safety Checker**: Blocks dangerous operations (e.g., mass deletions, system commands, file access)
56
- - **Read-Only Mode**: Enforced in production
57
- - **Audit Logging**: All executions are logged to `log/rails_active_mcp.log`
58
- - **Configurable**: Fine-tune what is allowed per environment
55
+ ### 1. console_execute
56
+ **Purpose:**
57
+ Execute Ruby code in the Rails console context with safety checks and timeout protection.
59
58
 
60
- ## Extending the Gem
61
- - Add custom tools by calling `RailsActiveMcp.server.register_tool` in an initializer or plugin.
62
- - Tools must define a name, description, input schema, and a handler block.
59
+ **Features:**
60
+ - Built-in dangerous operation detection
61
+ - Configurable execution timeout
62
+ - All executions logged for audit
63
+ - Safe execution environment
63
64
 
64
- ## Testing & Specification Adherence
65
- - All features are covered by RSpec tests in the `spec/` directory.
66
- - Follows standard Ruby/Rails conventions for gems, engines, and generators.
67
- - MCP protocol compliance is maintained as per [modelcontextprotocol.io](https://modelcontextprotocol.io/introduction).
65
+ **Example Usage in Claude:**
66
+ > "Execute `User.where(active: true).count`"
68
67
 
69
- ## Per-Tool Breakdown
68
+ ---
70
69
 
71
- ### 1. rails_console_execute
70
+ ### 2. model_info
72
71
  **Purpose:**
73
- Execute arbitrary Ruby code in the Rails console context, with safety checks and output capture.
74
-
75
- **Input Parameters:**
76
- - `code` (string, required): Ruby code to execute.
77
- - `safe_mode` (boolean, optional): Enable safety checks (default: true).
78
- - `timeout` (integer, optional): Timeout in seconds (default: 30).
79
- - `capture_output` (boolean, optional): Capture console output (default: true).
80
-
81
- **Output:**
82
- - On success: Code, result, output (if any), execution time, and notes.
83
- - On error: Error message and class.
84
-
85
- **Example Usage:**
86
- ```json
87
- {
88
- "method": "tools/call",
89
- "params": {
90
- "name": "rails_console_execute",
91
- "arguments": {
92
- "code": "User.count"
93
- }
94
- }
95
- }
96
- ```
72
+ Get detailed information about Rails models including schema, associations, and validations.
73
+
74
+ **Features:**
75
+ - Schema information (column types, constraints, indexes)
76
+ - Association details (has_many, belongs_to, has_one relationships)
77
+ - Validation rules and constraints
78
+ - Available instance and class methods
79
+
80
+ **Example Usage in Claude:**
81
+ > "Show me the User model structure"
97
82
 
98
83
  ---
99
84
 
100
- ### 2. rails_model_info
85
+ ### 3. safe_query
101
86
  **Purpose:**
102
- Get detailed information about a Rails model, including schema, associations, and validations.
103
-
104
- **Input Parameters:**
105
- - `model` (string, required): Model class name (e.g., "User").
106
- - `include_schema` (boolean, optional): Include database schema info (default: true).
107
- - `include_associations` (boolean, optional): Include model associations (default: true).
108
- - `include_validations` (boolean, optional): Include model validations (default: true).
109
-
110
- **Output:**
111
- - Model name, table, primary key, schema (columns, types, null/default), associations, validations.
112
- - On error: Error message (e.g., model not found).
113
-
114
- **Example Usage:**
115
- ```json
116
- {
117
- "method": "tools/call",
118
- "params": {
119
- "name": "rails_model_info",
120
- "arguments": {
121
- "model": "User"
122
- }
123
- }
124
- }
125
- ```
87
+ Execute safe, read-only database queries with automatic safety analysis.
88
+
89
+ **Features:**
90
+ - Read-only operations only (SELECT queries)
91
+ - Automatic query analysis for safety
92
+ - Result limiting to prevent large data dumps
93
+ - Works within your model definitions
94
+
95
+ **Example Usage in Claude:**
96
+ > "Get the 10 most recent orders"
126
97
 
127
98
  ---
128
99
 
129
- ### 3. rails_safe_query
100
+ ### 4. dry_run
130
101
  **Purpose:**
131
- Execute safe, read-only database queries on Rails models.
132
-
133
- **Input Parameters:**
134
- - `model` (string, required): Model class name (e.g., "User").
135
- - `method` (string, required): Query method (e.g., "where", "count").
136
- - `args` (array, optional): Arguments for the query method.
137
- - `limit` (integer, optional): Limit results (default: 100).
138
-
139
- **Output:**
140
- - Query string, count, and result (as inspected Ruby object).
141
- - On error: Error message.
142
-
143
- **Example Usage:**
144
- ```json
145
- {
146
- "method": "tools/call",
147
- "params": {
148
- "name": "rails_safe_query",
149
- "arguments": {
150
- "model": "User",
151
- "method": "where",
152
- "args": [{"active": true}],
153
- "limit": 10
154
- }
155
- }
156
- }
102
+ Analyze Ruby code for safety without executing it.
103
+
104
+ **Features:**
105
+ - Risk assessment and categorization
106
+ - Safety analysis with detailed feedback
107
+ - Recommendations for safer alternatives
108
+ - Zero execution guarantee
109
+
110
+ **Example Usage in Claude:**
111
+ > "Analyze this code for safety: `User.delete_all`"
112
+
113
+ ## Security & Safety
114
+ - **Safety Checker**: Blocks dangerous operations (mass deletions, system commands, file access)
115
+ - **Read-Only Detection**: Identifies and promotes safe read-only operations
116
+ - **Audit Logging**: All executions are logged with detailed context
117
+ - **Configurable**: Fine-tune safety levels per environment
118
+
119
+ ## Architecture
120
+
121
+ ### Built on Official MCP Ruby SDK
122
+ Rails Active MCP leverages the official MCP Ruby SDK for:
123
+
124
+ - **Professional Protocol Handling**: Robust JSON-RPC 2.0 implementation
125
+ - **Built-in Instrumentation**: Automatic timing and error reporting
126
+ - **Future-Proof**: Automatic updates as MCP specification evolves
127
+ - **Standards Compliance**: Full MCP protocol compatibility
128
+
129
+ ### Server Implementation
130
+ The server is implemented in `lib/rails_active_mcp/sdk/server.rb` and provides:
131
+
132
+ - **STDIO Transport**: Perfect for Claude Desktop integration
133
+ - **Tool Registration**: Automatic discovery of available tools
134
+ - **Error Handling**: Comprehensive error reporting and recovery
135
+ - **Rails Integration**: Deep integration with Rails applications
136
+
137
+ ### Tool Architecture
138
+ Each tool is implemented as a separate class in `lib/rails_active_mcp/sdk/tools/`:
139
+
140
+ - `ConsoleExecuteTool`: Safe code execution
141
+ - `ModelInfoTool`: Model introspection
142
+ - `SafeQueryTool`: Read-only database access
143
+ - `DryRunTool`: Code safety analysis
144
+
145
+ ## Testing & Development
146
+
147
+ ### Running Tests
148
+ ```bash
149
+ $ bundle exec rspec
157
150
  ```
158
151
 
159
- ---
152
+ ### Testing MCP Integration
153
+ ```bash
154
+ $ ./bin/test-mcp-output
155
+ ```
160
156
 
161
- ### 4. rails_dry_run
162
- **Purpose:**
163
- Analyze Ruby code for safety and risk without executing it.
164
-
165
- **Input Parameters:**
166
- - `code` (string, required): Ruby code to analyze.
167
-
168
- **Output:**
169
- - Code, safety status, read-only status, risk level, summary, violations, and recommendations.
170
-
171
- **Example Usage:**
172
- ```json
173
- {
174
- "method": "tools/call",
175
- "params": {
176
- "name": "rails_dry_run",
177
- "arguments": {
178
- "code": "User.delete_all"
179
- }
180
- }
181
- }
157
+ ### Debugging
158
+ Set the debug environment variable for detailed logging:
159
+ ```bash
160
+ $ RAILS_MCP_DEBUG=1 bundle exec rails-active-mcp-server
182
161
  ```
183
162
 
184
- ---
185
- For more details, see the main project README or source code.
163
+ ## Extending the Gem
164
+ The gem is designed to be extensible. You can add custom tools by:
165
+
166
+ 1. Creating new tool classes in your application
167
+ 2. Following the MCP tool interface pattern
168
+ 3. Registering tools with the server during initialization
169
+
170
+ Each tool must implement the standard MCP tool interface with proper input schemas and error handling.
171
+
172
+
173
+ For more details, see the main project README or explore the source code in `lib/rails_active_mcp/sdk/`.
@@ -1,120 +1,197 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'rack'
4
+ # Require essential gems first
5
5
  require 'json'
6
6
  require 'stringio'
7
7
 
8
- # Suppress ALL output immediately when not in debug mode to prevent MCP JSON protocol interference
8
+ # CRITICAL: Redirect stdout IMMEDIATELY for stdio mode to prevent any output interference
9
+ # This must happen before any other gem loading
9
10
  original_stdout = $stdout
10
11
  original_stderr = $stderr
11
12
 
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
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
17
30
  end
18
31
 
19
32
  # Initialize Rails environment if available (from current working directory)
20
33
  rails_loaded = false
34
+ rails_load_error = nil
21
35
  if File.exist?('config/environment.rb')
22
36
  begin
23
37
  require './config/environment'
24
38
  rails_loaded = true
39
+
40
+ # Log successful Rails loading
41
+ warn "[#{Time.now}] [RAILS-MCP] INFO: Rails environment loaded successfully" if should_redirect
25
42
  rescue StandardError => e
26
43
  # 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']
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']
29
48
  end
49
+ elsif should_redirect
50
+ warn "[#{Time.now}] [RAILS-MCP] INFO: No Rails environment found (config/environment.rb missing)"
30
51
  end
31
52
 
32
- # Restore stdout/stderr after Rails loading for non-debug stdio mode
33
- if ARGV.first == 'stdio' && !ENV['RAILS_MCP_DEBUG']
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
34
64
  $stdout = original_stdout
35
- $stderr = original_stderr
36
65
  end
37
66
 
38
67
  # Now load the gem
39
- require_relative '../lib/rails_active_mcp'
40
-
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)
43
- RailsActiveMcp.config.server_mode.to_s
44
- else
45
- 'stdio'
46
- end
47
- default_port = if rails_loaded && defined?(RailsActiveMcp) && RailsActiveMcp.respond_to?(:config)
48
- RailsActiveMcp.config.server_port
49
- else
50
- 3001
51
- end
52
- default_host = if rails_loaded && defined?(RailsActiveMcp) && RailsActiveMcp.respond_to?(:config)
53
- RailsActiveMcp.config.server_host
54
- else
55
- 'localhost'
56
- end
57
-
58
- transport = ARGV[0] || default_mode
59
- port = ARGV.include?('--port') ? ARGV[ARGV.index('--port') + 1].to_i : default_port
60
- host = ARGV.include?('--host') ? ARGV[ARGV.index('--host') + 1] : default_host
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
61
127
 
62
128
  case transport
63
129
  when 'stdio'
64
- # Stdio transport for Claude Desktop
65
- require_relative '../lib/rails_active_mcp/stdio_server'
66
-
130
+ # Stdio transport for Claude Desktop using MCP SDK
67
131
  begin
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
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}"
79
141
  end
80
142
 
81
- stdio_server = RailsActiveMcp::StdioServer.new
82
- stdio_server.start
143
+ server = RailsActiveMcp::Sdk::Server.new
144
+ server.run_stdio
83
145
  rescue Interrupt
146
+ warn "[#{Time.now}] [RAILS-MCP] INFO: Server interrupted by user" if should_redirect
84
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)
85
156
  end
86
157
 
87
158
  when 'http'
88
- # HTTP transport for other integrations
89
- puts 'Warning: Rails environment not loaded. Some features may not work properly.' unless rails_loaded
90
-
91
- puts "Starting Rails Active MCP Server on #{host}:#{port}"
92
- puts 'Press Ctrl+C to stop'
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)
93
164
 
94
- begin
95
- require 'webrick'
96
- require 'rack/handler/webrick'
97
-
98
- Rack::Handler::WEBrick.run(
99
- RailsActiveMcp::McpServer.new,
100
- Port: port,
101
- Host: host,
102
- Logger: WEBrick::Log.new(nil, WEBrick::BasicLog::WARN)
103
- )
104
- rescue LoadError => e
105
- puts 'Error: WEBrick not available. Please install: gem install webrick'
106
- puts 'Or use stdio mode for Claude Desktop: rails-active-mcp-server stdio'
107
- exit(1)
108
- rescue Interrupt
109
- puts "\nShutting down server..."
110
- end
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)
111
184
 
112
185
  else
113
- puts 'Usage: rails-active-mcp-server [stdio|http] [--port PORT] [--host HOST]'
114
- puts ' stdio: For Claude Desktop integration'
115
- puts ' http: For HTTP-based integrations'
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'
116
191
  puts ''
117
192
  puts 'Environment variables:'
118
- puts ' RAILS_MCP_DEBUG=1 Enable debug logging'
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.'
119
196
  exit(1)
120
197
  end