Class: MCPClient::ConfigParser
- Inherits:
-
Object
- Object
- MCPClient::ConfigParser
- Defined in:
- lib/mcp_client/config_parser.rb
Overview
Parses MCP server definition JSON files into configuration hashes
Constant Summary collapse
- RESERVED_KEYS =
Reserved JSON keys that shouldn’t be included in final config
%w[comment description].freeze
Instance Method Summary collapse
-
#determine_server_type(config, server_name) ⇒ String?
Determine the type of server from its configuration.
-
#extract_servers_data(data) ⇒ Hash
Extract server data from parsed JSON.
-
#initialize(file_path, logger: nil) ⇒ ConfigParser
constructor
A new instance of ConfigParser.
-
#parse ⇒ Hash<String, Hash>
Parse the JSON config and return a mapping of server names to clean config hashes.
-
#process_server_config(config, server_name) ⇒ Hash?
Process a single server configuration.
-
#valid_server_config?(config, server_name) ⇒ Boolean
Validate server configuration is a hash.
Constructor Details
#initialize(file_path, logger: nil) ⇒ ConfigParser
Returns a new instance of ConfigParser.
14 15 16 17 |
# File 'lib/mcp_client/config_parser.rb', line 14 def initialize(file_path, logger: nil) @file_path = file_path @logger = logger || Logger.new($stdout, level: Logger::WARN) end |
Instance Method Details
#determine_server_type(config, server_name) ⇒ String?
Determine the type of server from its configuration
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/mcp_client/config_parser.rb', line 106 def determine_server_type(config, server_name) type = config['type'] return type if type inferred_type = if config.key?('command') || config.key?('args') || config.key?('env') 'stdio' elsif config.key?('url') # Default to streamable_http unless URL contains "sse" url = config['url'].to_s.downcase url.include?('sse') ? 'sse' : 'streamable_http' end if inferred_type @logger.warn("'type' not specified for server '#{server_name}', inferring as '#{inferred_type}'.") return inferred_type end @logger.warn("Could not determine type for server '#{server_name}' (missing 'command' or 'url'); skipping.") nil end |
#extract_servers_data(data) ⇒ Hash
Extract server data from parsed JSON
50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/mcp_client/config_parser.rb', line 50 def extract_servers_data(data) if data.is_a?(Hash) && data.key?('mcpServers') && data['mcpServers'].is_a?(Hash) data['mcpServers'] elsif data.is_a?(Array) h = {} data.each_with_index { |cfg, idx| h[idx.to_s] = cfg } h elsif data.is_a?(Hash) { '0' => data } else @logger.warn("Invalid root JSON structure in #{@file_path}: #{data.class}") {} end end |
#parse ⇒ Hash<String, Hash>
Parse the JSON config and return a mapping of server names to clean config hashes
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/mcp_client/config_parser.rb', line 21 def parse content = File.read(@file_path) data = JSON.parse(content) servers_data = extract_servers_data(data) servers_data = filter_reserved_keys(servers_data) result = {} servers_data.each do |server_name, config| next unless valid_server_config?(config, server_name) server_config = process_server_config(config, server_name) next unless server_config # Add server name to the config server_config[:name] = server_name result[server_name] = server_config end result rescue Errno::ENOENT raise Errno::ENOENT, "Server definition file not found: #{@file_path}" rescue JSON::ParserError => e raise JSON::ParserError, "Invalid JSON in #{@file_path}: #{e.message}" end |
#process_server_config(config, server_name) ⇒ Hash?
Process a single server configuration
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/mcp_client/config_parser.rb', line 80 def process_server_config(config, server_name) type = determine_server_type(config, server_name) return nil unless type clean = { type: type.to_s } case type.to_s when 'stdio' parse_stdio_config(clean, config, server_name) when 'sse' return nil unless parse_sse_config?(clean, config, server_name) when 'streamable_http' return nil unless parse_streamable_http_config?(clean, config, server_name) when 'http' return nil unless parse_http_config?(clean, config, server_name) else @logger.warn("Unrecognized type '#{type}' for server '#{server_name}'; skipping.") return nil end clean end |
#valid_server_config?(config, server_name) ⇒ Boolean
Validate server configuration is a hash
69 70 71 72 73 74 |
# File 'lib/mcp_client/config_parser.rb', line 69 def valid_server_config?(config, server_name) return true if config.is_a?(Hash) @logger.warn("Configuration for server '#{server_name}' is not an object; skipping.") false end |