Class: RailsAiContext::McpConfigGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_ai_context/mcp_config_generator.rb

Overview

Generates per-tool MCP config files so each AI tool auto-discovers the MCP server.

Each tool has its own config file format:

Claude Code  → .mcp.json          (mcpServers key)
Cursor       → .cursor/mcp.json   (mcpServers key)
VS Code      → .vscode/mcp.json   (servers key)
OpenCode     → opencode.json      (mcp key, type: "local", command as array)
Codex CLI    → .codex/config.toml (TOML, [mcp_servers.NAME] section)

Constant Summary collapse

TOOL_CONFIGS =
{
  claude:   { path: ".mcp.json",          root_key: "mcpServers", format: :mcp_json },
  cursor:   { path: ".cursor/mcp.json",   root_key: "mcpServers", format: :mcp_json },
  copilot:  { path: ".vscode/mcp.json",   root_key: "servers",    format: :vscode_json },
  opencode: { path: "opencode.json",      root_key: "mcp",        format: :opencode_json },
  codex:    { path: ".codex/config.toml",  root_key: nil,          format: :codex_toml }
}.freeze
SERVER_NAME =
"rails-ai-context"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tools:, output_dir:, standalone: false, tool_mode: :mcp) ⇒ McpConfigGenerator

Returns a new instance of McpConfigGenerator.

Parameters:

  • tools (Array<Symbol>)

    selected AI tool keys (e.g. [:claude, :cursor])

  • output_dir (String)

    project root path

  • standalone (Boolean) (defaults to: false)

    true for standalone CLI mode

  • tool_mode (Symbol) (defaults to: :mcp)

    :mcp or :cli



31
32
33
34
35
36
# File 'lib/rails_ai_context/mcp_config_generator.rb', line 31

def initialize(tools:, output_dir:, standalone: false, tool_mode: :mcp)
  @tools = Array(tools).map(&:to_sym)
  @output_dir = output_dir
  @standalone = standalone
  @tool_mode = tool_mode
end

Class Method Details

.remove(tools:, output_dir:) ⇒ Array<String>

Removes only the rails-ai-context entry from each tool’s MCP config file, preserving other servers. Deletes the file only if no other entries remain.

Parameters:

  • tools (Array<Symbol>)

    tool keys to remove MCP entries from

  • output_dir (String)

    project root path

Returns:

  • (Array<String>)

    paths that were modified or deleted



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/rails_ai_context/mcp_config_generator.rb', line 235

def self.remove(tools:, output_dir:)
  cleaned = []
  Array(tools).map(&:to_sym).each do |tool|
    config = TOOL_CONFIGS[tool]
    next unless config

    path = File.join(output_dir, config[:path])
    next unless File.exist?(path)

    if config[:format] == :codex_toml
      cleaned << path if remove_toml_entry(path)
    else
      root_key = config[:root_key]
      cleaned << path if remove_json_entry(path, root_key)
    end
  end
  cleaned
end

Instance Method Details

#callHash

Returns { written: [paths], skipped: [paths] }.

Returns:

  • (Hash)

    { written: [paths], skipped: [paths] }



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rails_ai_context/mcp_config_generator.rb', line 39

def call
  return { written: [], skipped: [] } if @tool_mode == :cli

  written = []
  skipped = []

  @tools.each do |tool|
    config = TOOL_CONFIGS[tool]
    next unless config

    path = File.join(@output_dir, config[:path])
    result = generate_for(tool, path, config)
    case result
    when :written then written << path
    when :skipped then skipped << path
    end
  end

  { written: written, skipped: skipped }
end