rails-mcp-server 1.0.1 → 1.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77086c307fcceff18aac3bb1141c13a4b3de689342b65b276950156de22b09f0
4
- data.tar.gz: 7afb0b7e81b51540befce4ef6dacb0aaf731aa3afcbb5135267c1e1311846f79
3
+ metadata.gz: 8d12279954da579f2d3998c4ffa14a016895fbf71bca6dc13ac5d3ba058a1429
4
+ data.tar.gz: e1c35ecb2ae0dd6e0dcd862d24c650979777449e5dcece15620d39759c580b9e
5
5
  SHA512:
6
- metadata.gz: '03796522301b8d8d7c3ab258c67a146847d41ae909534148bc2015f7e11fe0156cbec424218de469f85c2f992958b3831b9b4a51da1799f9235b0c39469d5c4c'
7
- data.tar.gz: 9511d7eaa3fdd2a3e05fa42cfd4ab7b102508641ce07831bacb8927311c1b275af4fed19e248754d28db28bcf7c5c82cdcb38e0b4ef9d7335bbee8100372214d
6
+ metadata.gz: 6a7a701f2f181d219e5e781f7d5ce5b372f7a841b37b6f0d82803ac613b1e00d92af72aba369b70776fda2a82be9084d4263bd0b663b115415d5b436d7c27644
7
+ data.tar.gz: 3acd59344bdc020e0d2a175835da56e837e5043ae7effdb913862f95b3aa938ec4ec395c812dd440460f8629b9fdfbfb9fe9250f28c781e1775de4d34e1f37ea
data/README.md CHANGED
@@ -15,6 +15,8 @@ This Rails MCP Server implements the MCP specification to give AI models access
15
15
  - View Rails routes
16
16
  - Inspect model information
17
17
  - Get database schema information
18
+ - Analyze controller-view relationships
19
+ - Analyze environment configurations
18
20
  - Follow the Model Context Protocol standard
19
21
 
20
22
  ## Installation
@@ -110,28 +112,44 @@ Replace "/home/your_user/.rbenv/shims/ruby" with your actual path for the Ruby s
110
112
 
111
113
  ## Usage
112
114
 
113
- Start the server:
115
+ ### Starting the server
116
+
117
+ The Rails MCP Server can run in two modes:
118
+
119
+ 1. **STDIO mode (default)**: Communicates over standard input/output for direct integration with clients like Claude Desktop.
120
+ 2. **HTTP mode**: Runs as an HTTP server with JSON-RPC and Server-Sent Events (SSE) endpoints.
114
121
 
115
122
  ```bash
123
+ # Start in default STDIO mode
116
124
  rails-mcp-server
125
+
126
+ # Start in HTTP mode on the default port (6029)
127
+ rails-mcp-server --mode http
128
+
129
+ # Start in HTTP mode on a custom port
130
+ rails-mcp-server --mode http -p 8080
117
131
  ```
118
132
 
133
+ When running in HTTP mode, the server provides two endpoints:
134
+
135
+ - JSON-RPC endpoint: `http://localhost:<port>/mcp/messages`
136
+ - SSE endpoint: `http://localhost:<port>/mcp/sse`
137
+
119
138
  ### Logging Options
120
139
 
121
140
  The server logs to a file in the `./log` directory by default. You can customize logging with these options:
122
141
 
123
142
  ```bash
124
- # Set the log level (debug, info, warn, error, fatal)
143
+ # Set the log level (debug, info, error)
125
144
  rails-mcp-server --log-level debug
126
145
  ```
127
146
 
128
147
  ## How the Server Works
129
148
 
130
- The Rails MCP Server implements the Model Context Protocol over standard input/output (stdio). It:
149
+ The Rails MCP Server implements the Model Context Protocol using either:
131
150
 
132
- 1. Reads JSON-RPC 2.0 requests from standard input
133
- 2. Processes the requests using the appropriate tools
134
- 3. Returns JSON-RPC 2.0 responses to standard output
151
+ - **STDIO mode**: Reads JSON-RPC 2.0 requests from standard input and returns responses to standard output.
152
+ - **HTTP mode**: Provides HTTP endpoints for JSON-RPC 2.0 requests and Server-Sent Events.
135
153
 
136
154
  Each request includes a sequence number to match requests with responses, as defined in the MCP specification.
137
155
 
@@ -141,31 +159,13 @@ The server provides the following tools for interacting with Rails projects:
141
159
 
142
160
  ### 1. `switch_project`
143
161
 
144
- Switch the active Rails project.
162
+ **Description:** Change the active Rails project to interact with a different codebase. Must be called before using other tools. Available projects are defined in the projects.yml configuration file.
145
163
 
146
164
  **Parameters:**
147
165
 
148
166
  - `project_name`: (String, required) Name of the project to switch to, as defined in the projects.yml file
149
167
 
150
- **Example:**
151
-
152
- ```json
153
- {
154
- "jsonrpc": "2.0",
155
- "id": "123",
156
- "method": "tools/call",
157
- "params": {
158
- "name": "switch_project",
159
- "arguments": {
160
- "project_name": "blog"
161
- }
162
- }
163
- }
164
- ```
165
-
166
- **Description:** Change the active Rails project to interact with a different codebase. Must be called before using other tools. Available projects are defined in the projects.yml configuration file.
167
-
168
- Examples:
168
+ #### Examples
169
169
 
170
170
  ```
171
171
  Can you switch to the "store" project so we can explore it?
@@ -181,27 +181,11 @@ Switch to the "ecommerce" project and give me a summary of the codebase.
181
181
 
182
182
  ### 2. `get_project_info`
183
183
 
184
- Get information about the current Rails project, including version, directory structure, and configuration.
184
+ **Description:** Retrieve comprehensive information about the current Rails project, including Rails version, directory structure, API-only status, and overall project organization. Useful for initial project exploration and understanding the codebase structure.
185
185
 
186
186
  **Parameters:** None
187
187
 
188
- **Example:**
189
-
190
- ```json
191
- {
192
- "jsonrpc": "2.0",
193
- "id": "124",
194
- "method": "tools/call",
195
- "params": {
196
- "name": "get_project_info",
197
- "arguments": {}
198
- }
199
- }
200
- ```
201
-
202
- **Description:** Retrieve comprehensive information about the current Rails project, including Rails version, directory structure, API-only status, and overall project organization.
203
-
204
- Examples:
188
+ #### Examples
205
189
 
206
190
  ```
207
191
  Now that we're in the blog project, can you give me an overview of the project structure and Rails version?
@@ -217,33 +201,14 @@ I'd like to understand the high-level architecture of this project. Can you prov
217
201
 
218
202
  ### 3. `list_files`
219
203
 
220
- List files in the Rails project, with optional directory path and pattern filtering.
204
+ **Description:** List files in the Rails project matching specific criteria. Use this to explore project directories or locate specific file types. If no parameters are provided, lists files in the project root.
221
205
 
222
206
  **Parameters:**
223
207
 
224
- - `directory`: (String, optional) Directory path relative to the project root
225
- - `pattern`: (String, optional) File pattern to match (e.g., "*.rb")
226
-
227
- **Example:**
228
-
229
- ```json
230
- {
231
- "jsonrpc": "2.0",
232
- "id": "125",
233
- "method": "tools/call",
234
- "params": {
235
- "name": "list_files",
236
- "arguments": {
237
- "directory": "app/models",
238
- "pattern": "*.rb"
239
- }
240
- }
241
- }
242
- ```
243
-
244
- **Description:** List files in the Rails project matching specific criteria. Use this to explore project directories or locate specific file types.
208
+ - `directory`: (String, optional) Directory path relative to the project root (e.g., 'app/models', 'config')
209
+ - `pattern`: (String, optional) File pattern using glob syntax (e.g., '.rb' for Ruby files, '.erb' for ERB templates)
245
210
 
246
- Examples:
211
+ #### Examples
247
212
 
248
213
  ```
249
214
  Can you list all the model files in this project?
@@ -263,31 +228,13 @@ List all the JavaScript files in the app/javascript directory.
263
228
 
264
229
  ### 4. `get_file`
265
230
 
266
- Get the content of a file in the Rails project with syntax highlighting.
231
+ **Description:** Retrieve the complete content of a specific file with syntax highlighting. Use this to examine implementation details, configurations, or any text file in the project.
267
232
 
268
233
  **Parameters:**
269
234
 
270
- - `path`: (String, required) File path relative to the project root
271
-
272
- **Example:**
273
-
274
- ```json
275
- {
276
- "jsonrpc": "2.0",
277
- "id": "126",
278
- "method": "tools/call",
279
- "params": {
280
- "name": "get_file",
281
- "arguments": {
282
- "path": "app/models/user.rb"
283
- }
284
- }
285
- }
286
- ```
235
+ - `path`: (String, required) File path relative to the project root (e.g., 'app/models/user.rb', 'config/routes.rb')
287
236
 
288
- **Description:** Retrieve the complete content of a specific file with syntax highlighting.
289
-
290
- Examples:
237
+ #### Examples
291
238
 
292
239
  ```
293
240
  Can you show me the content of the User model file?
@@ -307,27 +254,11 @@ I'd like to examine the routes file. Can you display the content of config/route
307
254
 
308
255
  ### 5. `get_routes`
309
256
 
310
- Get the routes defined in the Rails project.
257
+ **Description:** Retrieve all HTTP routes defined in the Rails application with their associated controllers and actions. Equivalent to running 'rails routes' command. This helps understand the API endpoints or page URLs available in the application.
311
258
 
312
259
  **Parameters:** None
313
260
 
314
- **Example:**
315
-
316
- ```json
317
- {
318
- "jsonrpc": "2.0",
319
- "id": "127",
320
- "method": "tools/call",
321
- "params": {
322
- "name": "get_routes",
323
- "arguments": {}
324
- }
325
- }
326
- ```
327
-
328
- **Description:** Retrieve all HTTP routes defined in the Rails application with their associated controllers and actions.
329
-
330
- Examples:
261
+ #### Examples
331
262
 
332
263
  ```
333
264
  Can you show me all the routes defined in this application?
@@ -341,33 +272,15 @@ I need to understand the API endpoints available in this project. Can you list t
341
272
  Show me the routing configuration for this Rails app so I can see how the URLs are structured.
342
273
  ```
343
274
 
344
- ### 6. `get_models`
275
+ ### 6. `analyze_models`
345
276
 
346
- Get information about the models in the Rails project, including schema, associations, and definitions.
277
+ **Description:** Retrieve detailed information about Active Record models in the project. When called without parameters, lists all model files. When a specific model is specified, returns its schema, associations (has_many, belongs_to, has_one), and complete source code.
347
278
 
348
279
  **Parameters:**
349
280
 
350
- - `model_name`: (String, optional) Name of a specific model to get information for
351
-
352
- **Example:**
353
-
354
- ```json
355
- {
356
- "jsonrpc": "2.0",
357
- "id": "128",
358
- "method": "tools/call",
359
- "params": {
360
- "name": "get_models",
361
- "arguments": {
362
- "model_name": "User"
363
- }
364
- }
365
- }
366
- ```
367
-
368
- **Description:** Retrieve detailed information about Active Record models in the project.
281
+ - `model_name`: (String, optional) Class name of a specific model to get detailed information for (e.g., 'User', 'Product'). Use CamelCase, not snake_case.
369
282
 
370
- Examples:
283
+ #### Examples
371
284
 
372
285
  ```
373
286
  Can you list all the models in this Rails project?
@@ -387,31 +300,13 @@ What are all the models in this application, and can you then show me details fo
387
300
 
388
301
  ### 7. `get_schema`
389
302
 
390
- Get the database schema for the Rails project or for a specific table.
303
+ **Description:** Retrieve database schema information for the Rails application. Without parameters, returns all tables and the complete schema.rb. With a table name, returns detailed column information including data types, constraints, and foreign keys for that specific table.
391
304
 
392
305
  **Parameters:**
393
306
 
394
- - `table_name`: (String, optional) Name of a specific table to get schema for
307
+ - `table_name`: (String, optional) Database table name to get detailed schema information for (e.g., 'users', 'products'). Use snake_case, plural form.
395
308
 
396
- **Example:**
397
-
398
- ```json
399
- {
400
- "jsonrpc": "2.0",
401
- "id": "129",
402
- "method": "tools/call",
403
- "params": {
404
- "name": "get_schema",
405
- "arguments": {
406
- "table_name": "users"
407
- }
408
- }
409
- }
410
- ```
411
-
412
- **Description:** Retrieve database schema information for the Rails application.
413
-
414
- Examples:
309
+ #### Examples
415
310
 
416
311
  ```
417
312
  Can you show me the complete database schema for this Rails application?
@@ -429,42 +324,69 @@ Show me the columns and their data types in the products table.
429
324
  I need to understand the database design. Can you first list all tables and then show me details for the orders table?
430
325
  ```
431
326
 
432
- ## Integration with LLM Clients
433
-
434
- This server is designed to be integrated with LLM clients that support the Model Context Protocol, such as Claude Desktop or other MCP-compatible applications.
327
+ ### 8. `analyze_controller_views`
435
328
 
436
- To use with an MCP client:
329
+ **Description:** Analyze the relationships between controllers, their actions, and corresponding views to understand the application's UI flow.
437
330
 
438
- 1. Start the Rails MCP Server
439
- 2. Connect your MCP-compatible client to the server
440
- 3. The client will be able to use the available tools to interact with your Rails projects
331
+ **Parameters:**
441
332
 
442
- ## Manual Testing
333
+ - `controller_name`: (String, optional) Name of a specific controller to analyze (e.g., 'UsersController' or 'users'). If omitted, all controllers will be analyzed.
443
334
 
444
- You can manually test the server by sending JSON-RPC requests to its standard input:
335
+ #### Examples
445
336
 
446
- ```bash
447
- echo '0 {"jsonrpc":"2.0","id":"test-123","method":"ping"}' | rails-mcp-server
448
337
  ```
338
+ Can you analyze the Users controller and its views to help me understand the UI flow?
339
+ ```
340
+
341
+ ### 9. `analyze_environment_config`
342
+
343
+ **Description:** Analyze environment configurations to identify inconsistencies, security issues, and missing variables across environments.
449
344
 
450
- Expected response:
345
+ **Parameters:** None
346
+
347
+ #### Examples
451
348
 
452
349
  ```
453
- 0 {"jsonrpc":"2.0","id":"test-123","result":{"version":"1.0.0"}}
350
+ Can you analyze the environment configurations to find any security issues or missing environment variables?
454
351
  ```
455
352
 
456
- Or test multiple commands in sequence:
353
+ ## Integration with LLM Clients
457
354
 
458
- ```bash
459
- (echo '0 {"jsonrpc":"2.0","id":"test-123","method":"tools/list"}'; sleep 1; echo '1 {"jsonrpc":"2.0","id":"test-456","method":"tools/call","params":{"name":"switch_project","arguments":{"project_name":"blog"}}}') | rails-mcp-server
460
- ```
355
+ This server is designed to be integrated with LLM clients that support the Model Context Protocol, such as Claude Desktop or other MCP-compatible applications.
356
+ To use with an MCP client:
461
357
 
462
- You can also use `jq` to parse the output and format it nicely:
358
+ 1. Start the Rails MCP Server (it will use STDIO mode by default)
359
+ 1. Connect your MCP-compatible client to the server
360
+ 1. The client will be able to use the available tools to interact with your Rails projects
463
361
 
464
- ```bash
465
- echo '0 {"jsonrpc":"2.0","id":"list-tools","method":"tools/list"}' | rails-mcp-server | sed 's/^[0-9]* //' | jq '.result.tools'
362
+ ## Testing and Debugging
363
+
364
+ The easiest way to test and debug the Rails MCP Server is by using the MCP Inspector, a developer tool designed specifically for testing and debugging MCP servers.
365
+
366
+ To use MCP Inspector with Rails MCP Server:
367
+
368
+ ```
369
+ # Install and run MCP Inspector with your Rails MCP Server
370
+ npm -g install @modelcontextprotocol/inspector
371
+
372
+ npx @modelcontextprotocol/inspector /path/to/rails-mcp-server
466
373
  ```
467
374
 
375
+ This will:
376
+
377
+ 1. Start your Rails MCP Server in HTTP mode
378
+ 1. Launch the MCP Inspector UI in your browser (default port: 6274)
379
+ 1. Set up an MCP Proxy server (default port: 6277)
380
+
381
+ In the MCP Inspector UI, you can:
382
+
383
+ - See all available tools
384
+ - Execute tool calls interactively
385
+ - View request and response details
386
+ - Debug issues in real-time
387
+
388
+ The Inspector UI provides an intuitive interface to interact with your MCP server, making it easy to test and debug your Rails MCP Server implementation.
389
+
468
390
  ## License
469
391
 
470
392
  This Rails MCP server is released under the MIT License, a permissive open-source license that allows for free use, modification, distribution, and private use.
data/exe/rails-mcp-server CHANGED
@@ -1,21 +1,17 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "pathname"
3
+ require "bundler/setup"
4
4
 
5
- # Get script directory and project root
6
- bin_dir = Pathname.new(__FILE__).dirname
7
- root_dir = bin_dir.parent
5
+ require "fast_mcp"
6
+ require "rack"
7
+ require "rack/handler/puma"
8
+ require "puma"
9
+ require "puma/configuration"
10
+ require "puma/launcher"
11
+ require_relative "../lib/rails_mcp_server"
8
12
 
9
- # Check if server script exists
10
- server_script = root_dir.join("lib", "rails_mcp_server.rb")
11
- unless server_script.exist?
12
- puts "Error: rails_mcp_server.rb not found in lib directory (#{root_dir}/lib)"
13
- exit 1
14
- end
15
-
16
- # Show version if requested
17
13
  if ARGV[0] == "version"
18
- puts "Rails MCP Server version 1.0.0"
14
+ puts "Rails MCP Server version #{RailsMcpServer::VERSION}"
19
15
  exit 0
20
16
  end
21
17
 
@@ -27,14 +23,90 @@ if ARGV[0] == "--help" || ARGV[0] == "-h"
27
23
  puts ""
28
24
  puts "Options:"
29
25
  puts " --log-level LEVEL Log level: debug, info, warn, error (default: info)"
26
+ puts " --mode MODE Server mode: http or stdio (default: stdio)"
27
+ puts " -p, --port PORT Port to listen on (default: 6029)"
30
28
  puts " version Display version information"
31
29
  puts " --help, -h Display this help message"
32
30
  puts ""
33
31
  puts "Example:"
34
- puts " #{File.basename($0)} --log-level debug"
32
+ puts " #{File.basename($0)} --log-level debug -p 6060"
33
+ puts " #{File.basename($0)} --mode stdio"
35
34
  exit 0
36
35
  end
37
36
 
38
- # Change to root directory and execute server script
39
- Dir.chdir(root_dir)
40
- load server_script
37
+ # Default values
38
+ port = 6029
39
+ mode = "stdio"
40
+
41
+ # Parse command-line arguments
42
+ i = 0
43
+ while i < ARGV.length
44
+ case ARGV[i]
45
+ when "--log-level"
46
+ log_level = ARGV[i + 1].to_sym
47
+ i += 2
48
+ when "-p", "--port"
49
+ port = ARGV[i + 1].to_i
50
+ i += 2
51
+ when "--mode"
52
+ mode = ARGV[i + 1].downcase
53
+ unless ["http", "stdio"].include?(mode) # rubocop:disable Performance/CollectionLiteralInLoop
54
+ puts "Error: Invalid mode '#{mode}'. Must be 'http' or 'stdio'."
55
+ exit 1
56
+ end
57
+ i += 2
58
+ else
59
+ i += 1
60
+ end
61
+ end
62
+
63
+ RailsMcpServer.config do |config|
64
+ config.log_level = log_level
65
+ end
66
+
67
+ RailsMcpServer.log(:info, "Starting Rails MCP Server in #{mode} mode...")
68
+
69
+ # Create tools configuration for both modes
70
+ def setup_mcp_tools(server)
71
+ server.register_tools(RailsMcpServer::SwitchProject, RailsMcpServer::ProjectInfo,
72
+ RailsMcpServer::ListFiles, RailsMcpServer::GetFile, RailsMcpServer::GetRoutes, RailsMcpServer::AnalyzeModels,
73
+ RailsMcpServer::GetSchema, RailsMcpServer::AnalyzeControllerViews, RailsMcpServer::AnalyzeEnvironmentConfig)
74
+ end
75
+
76
+ case mode
77
+ when "http"
78
+ puts "Starting Rack application with MCP middleware on http://localhost:#{port}"
79
+ puts "MCP endpoints:"
80
+ puts " - http://localhost:#{port}/mcp/sse (SSE endpoint)"
81
+ puts " - http://localhost:#{port}/mcp/messages (JSON-RPC endpoint)"
82
+ puts "Press Ctrl+C to stop"
83
+
84
+ rack_app = ->(env) {
85
+ [200, {"Content-Type" => "text/plain"}, ["Rails MCP Server #{RailsMcpServer::VERSION}"]]
86
+ }
87
+
88
+ mcp_app = FastMcp.rack_middleware(
89
+ rack_app,
90
+ name: "rails-mcp-server", version: RailsMcpServer::VERSION,
91
+ logger: RailsMcpServer.logger
92
+ ) { |server| setup_mcp_tools(server) }
93
+
94
+ app = Rack::Builder.new { run mcp_app }
95
+ config = Puma::Configuration.new do |user_config|
96
+ user_config.bind "tcp://localhost:#{port}"
97
+ user_config.app app
98
+ end
99
+
100
+ launcher = Puma::Launcher.new(config)
101
+ launcher.run
102
+ when "stdio"
103
+ RailsMcpServer.log(:info, "Starting MCP server in STDIO mode...")
104
+
105
+ server = FastMcp::Server.new(name: "rails-mcp-server", version: RailsMcpServer::VERSION)
106
+ setup_mcp_tools(server)
107
+
108
+ server.start
109
+ end
110
+
111
+ RailsMcpServer.log(:info, "Stopping Rails MCP Server...")
112
+ exit
@@ -118,7 +118,8 @@ end
118
118
 
119
119
  # Update configuration
120
120
  config["mcpServers"] ||= {}
121
- config["mcpServers"]["railsMcpServer"] = {"command" => "ruby", "args" => [server_path]}
121
+ # config["mcpServers"]["railsMcpServer"] = {"command" => "ruby", "args" => [server_path]}
122
+ config["mcpServers"]["railsMcpServer"] = {"command" => server_pathi, "args" => []}
122
123
 
123
124
  # Write configuration back to file
124
125
  File.write(claude_config_file, JSON.pretty_generate(config))
@@ -0,0 +1,72 @@
1
+ require "logger"
2
+
3
+ module RailsMcpServer
4
+ class Config
5
+ attr_accessor :logger, :log_level, :projects, :current_project, :active_project_path
6
+
7
+ def self.setup
8
+ new.tap do |instance|
9
+ yield(instance) if block_given?
10
+ end
11
+ end
12
+
13
+ def initialize
14
+ @log_level = Logger::INFO
15
+ @config_dir = get_config_dir
16
+ @current_project = nil
17
+ @active_project_path = nil
18
+
19
+ configure_logger
20
+ load_projects
21
+ end
22
+
23
+ private
24
+
25
+ def load_projects
26
+ projects_file = File.join(@config_dir, "projects.yml")
27
+ @projects = {}
28
+
29
+ @logger.add(Logger::INFO, "Loading projects from: #{projects_file}")
30
+
31
+ # Create empty projects file if it doesn't exist
32
+ unless File.exist?(projects_file)
33
+ @logger.add(:info, "Creating empty projects file: #{projects_file}")
34
+ FileUtils.mkdir_p(File.dirname(projects_file))
35
+ File.write(projects_file, "# Rails MCP Projects\n# Format: project_name: /path/to/project\n")
36
+ end
37
+
38
+ @projects = YAML.load_file(projects_file) || {}
39
+ found_projects_size = @projects.size
40
+ @logger.add(Logger::INFO, "Loaded #{found_projects_size} projects: #{@projects.keys.join(", ")}")
41
+
42
+ if found_projects_size.zero?
43
+ message = "No projects found.\nPlease add a project to #{projects_file} and try again."
44
+ puts message
45
+ @logger.add(Logger::ERROR, message)
46
+ exit 1
47
+ end
48
+ end
49
+
50
+ def configure_logger
51
+ FileUtils.mkdir_p(File.join(@config_dir, "log"))
52
+ log_file = File.join(@config_dir, "log", "rails_mcp_server.log")
53
+
54
+ @logger = Logger.new(log_file)
55
+ @logger.level = @log_level
56
+
57
+ @logger.formatter = proc do |severity, datetime, progname, msg|
58
+ "[#{datetime.strftime("%Y-%m-%d %H:%M:%S")}] #{severity}: #{msg}\n"
59
+ end
60
+ end
61
+
62
+ def get_config_dir
63
+ # Use XDG_CONFIG_HOME if set, otherwise use ~/.config
64
+ xdg_config_home = ENV["XDG_CONFIG_HOME"]
65
+ if xdg_config_home && !xdg_config_home.empty?
66
+ File.join(xdg_config_home, "rails-mcp")
67
+ else
68
+ File.join(Dir.home, ".config", "rails-mcp")
69
+ end
70
+ end
71
+ end
72
+ end