Class: Mcp::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/mcp/config.rb

Overview

Reads and writes MCP server configuration from a TOML file at DEFAULT_PATH. Supports HTTP and stdio transports. Secrets stored in the encrypted secrets table are interpolated via ${credential:key_name} syntax in any string value.

Examples:

Config file format (~/.anima/mcp.toml)

[servers.mythonix]
transport = "http"
url = "http://localhost:3000/mcp/v2"

[servers.linear]
transport = "http"
url = "https://mcp.linear.app/mcp"
headers = { Authorization = "Bearer ${credential:linear_api_key}" }

[servers.filesystem]
transport = "stdio"
command = "mcp-server-filesystem"
args = ["--root", "/workspace"]

Constant Summary collapse

DEFAULT_PATH =
File.expand_path("~/.anima/mcp.toml")
CREDENTIAL_PATTERN =

Pattern matching ‘$credential:key_name` for credential interpolation.

/\$\{credential:(\w+)\}/
VALID_NAME_PATTERN =

Bare TOML keys: letters, digits, hyphens, underscores.

/\A[A-Za-z0-9_-]+\z/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path: DEFAULT_PATH, logger: nil) ⇒ Config

Returns a new instance of Config.

Parameters:

  • path (String) (defaults to: DEFAULT_PATH)

    path to the TOML config file

  • logger (#warn, nil) (defaults to: nil)

    optional logger for warning output



41
42
43
44
45
46
# File 'lib/mcp/config.rb', line 41

def initialize(path: DEFAULT_PATH, logger: nil)
  @path = path
  @logger = logger
  @warnings = []
  @config_cache = nil
end

Instance Attribute Details

#warningsArray<String> (readonly)

Warnings accumulated during parsing (missing credentials, invalid entries).

Returns:

  • (Array<String>)


37
38
39
# File 'lib/mcp/config.rb', line 37

def warnings
  @warnings
end

Instance Method Details

#add_server(name, settings) ⇒ Object

Adds a server entry to the configuration file. Creates the file and parent directories if they don’t exist.

Parameters:

  • name (String)

    unique server identifier (letters, digits, hyphens, underscores)

  • settings (Hash<String, Object>)

    server configuration (transport, url/command, etc.)

Raises:

  • (ArgumentError)

    if name is invalid or already exists



64
65
66
67
68
69
70
71
72
73
# File 'lib/mcp/config.rb', line 64

def add_server(name, settings)
  validate_name!(name)
  config = load_config
  servers = config["servers"] ||= {}

  raise ArgumentError, "server '#{name}' already exists" if servers.key?(name)

  servers[name] = settings
  write_config(config)
end

#all_serversArray<Hash>

Returns all configured servers with raw (pre-interpolation) settings. Intended for display in CLI commands where showing literal ${credential:…} placeholders is more useful than resolved values.

Returns:

  • (Array<Hash>)

    servers with string keys from TOML plus “name”



53
54
55
56
# File 'lib/mcp/config.rb', line 53

def all_servers
  servers = load_config["servers"] || {}
  servers.map { |name, settings| settings.merge("name" => name) }
end

#http_serversArray<Hash>

Returns HTTP server configurations from the config file.

Returns:

  • (Array<Hash>)

    server configs with :name, :url, :headers keys



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/mcp/config.rb', line 92

def http_servers
  servers_by_transport("http") do |name, settings|
    url = settings["url"]
    unless url
      warn_and_skip("server '#{name}' has transport=http but no url")
      next
    end

    {
      name: name,
      url: interpolate_credentials(url),
      headers: interpolate_hash_values(settings["headers"] || {})
    }
  end
end

#remove_server(name) ⇒ Object

Removes a server entry from the configuration file.

Parameters:

  • name (String)

    server identifier to remove

Raises:

  • (ArgumentError)

    if server name not found



79
80
81
82
83
84
85
86
87
# File 'lib/mcp/config.rb', line 79

def remove_server(name)
  config = load_config
  servers = config["servers"] || {}

  raise ArgumentError, "server '#{name}' not found" unless servers.key?(name)

  servers.delete(name)
  write_config(config)
end

#stdio_serversArray<Hash>

Returns stdio server configurations from the config file.

Returns:

  • (Array<Hash>)

    server configs with :name, :command, :args, :env keys



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/mcp/config.rb', line 111

def stdio_servers
  servers_by_transport("stdio") do |name, settings|
    command = settings["command"]
    unless command
      warn_and_skip("server '#{name}' has transport=stdio but no command")
      next
    end

    {
      name: name,
      command: interpolate_credentials(command),
      args: (settings["args"] || []).map { |arg| interpolate_credentials(arg) },
      env: interpolate_hash_values(settings["env"] || {})
    }
  end
end