Packages
fnord
0.8.42
0.9.40
0.9.39
0.9.38
0.9.37
0.9.36
0.9.35
0.9.34
0.9.33
0.9.32
0.9.31
0.9.30
0.9.29
0.9.28
0.9.27
0.9.26
0.9.25
0.9.24
0.9.23
0.9.22
0.9.21
0.9.20
0.9.19
0.9.18
0.9.17
0.9.16
0.9.15
0.9.14
0.9.13
0.9.12
0.9.11
0.9.10
0.9.9
0.9.8
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.99
0.8.98
0.8.97
0.8.96
0.8.95
0.8.94
0.8.93
0.8.92
0.8.91
0.8.90
0.8.89
0.8.88
0.8.87
0.8.86
0.8.85
0.8.84
0.8.83
0.8.82
0.8.81
0.8.80
0.8.79
0.8.78
0.8.77
0.8.76
0.8.75
0.8.74
0.8.73
0.8.72
0.8.71
0.8.70
0.8.69
0.8.68
0.8.67
0.8.66
0.8.65
0.8.64
0.8.63
0.8.62
0.8.61
0.8.60
0.8.59
0.8.58
0.8.57
0.8.56
0.8.55
0.8.54
0.8.53
0.8.52
0.8.51
0.8.50
0.8.49
0.8.48
0.8.47
0.8.46
0.8.45
0.8.44
0.8.43
0.8.42
0.8.41
0.8.40
0.8.39
0.8.38
0.8.37
0.8.36
0.8.35
0.8.34
0.8.33
0.8.32
0.8.31
0.8.30
0.8.29
0.8.27
0.8.26
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.1
0.8.0
0.7.24
0.7.23
0.7.22
0.7.21
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.3
0.7.2
0.7.1
0.7.0
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.1
0.6.0
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.44
0.4.43
0.4.42
0.4.41
0.4.40
0.4.39
0.4.38
0.4.37
0.4.36
0.4.35
0.4.34
0.4.33
0.4.32
0.4.30
0.4.29
0.4.28
0.4.27
0.4.26
0.4.25
0.4.24
0.4.23
0.4.22
0.4.21
0.4.20
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.0
0.2.0
0.1.0
AI code archaeology
Current section
Files
Jump to
Current section
Files
lib/cmd/config/mcp.ex
defmodule Cmd.Config.MCP do
@moduledoc false
alias Cmd.Config.Utils
@spec run(map(), list(), list()) :: :ok
def run(opts, [:mcp, :list], _unknown) do
settings = Settings.new()
cond do
opts[:effective] ->
Settings.MCP.effective_config(settings)
|> Jason.encode!(pretty: true)
|> IO.puts()
opts[:global] ->
Settings.MCP.get_config(settings, :global)
|> Jason.encode!(pretty: true)
|> IO.puts()
# project scope explicitly via --project
opts[:project] ->
# verify project configuration exists in settings
case Settings.get_project_data(settings, opts[:project]) do
nil ->
UI.error("Project not specified or not found")
_proj_data ->
# activate project context and print config
Settings.set_project(opts[:project])
Settings.MCP.get_config(settings, :project)
|> Jason.encode!(pretty: true)
|> IO.puts()
end
# default to current project in settings
true ->
case Settings.get_selected_project() do
{:ok, _proj} ->
Settings.MCP.get_config(settings, :project)
|> Jason.encode!(pretty: true)
|> IO.puts()
{:error, _} ->
UI.error("Project not specified or not found")
end
end
end
def run(opts, [:mcp, :check], _unknown) do
if opts[:project], do: Settings.set_project(opts[:project])
Services.MCP.start()
Services.MCP.test()
|> Jason.encode!(pretty: true)
|> IO.puts()
end
# Unified entry for add, update, remove
def run(opts, [:mcp, action], args) when action in [:add, :update, :remove] do
if opts[:project], do: Settings.set_project(opts[:project])
case Utils.require_key(opts, args, :name, "Server name") do
{:error, msg} ->
UI.error(msg)
{:ok, name} ->
do_mcp_action(opts, action, name)
end
end
# ----------------------------------------------------------------------------
# Helpers
# ----------------------------------------------------------------------------
@spec build_server_config_from_opts(map()) :: map()
defp build_server_config_from_opts(opts) do
%{}
|> maybe_put("transport", opts[:transport] || "stdio")
|> maybe_put("command", opts[:command])
|> maybe_put("args", opts[:arg] || [])
|> maybe_put("base_url", opts[:base_url])
|> maybe_put("headers", parse_kv_list(opts[:header] || []))
|> maybe_put("env", parse_kv_list(opts[:env] || []))
|> maybe_put("timeout_ms", opts[:timeout_ms])
end
@spec maybe_put(map(), String.t(), any()) :: map()
defp maybe_put(map, _key, nil), do: map
defp maybe_put(map, key, value), do: Map.put(map, key, value)
@spec parse_kv_list(nil | [String.t()]) :: map()
defp parse_kv_list(nil), do: %{}
defp parse_kv_list(list) when is_list(list) do
Enum.reduce(list, %{}, fn kv, acc ->
case String.split(kv, "=", parts: 2) do
[k, v] -> Map.put(acc, k, v)
_ -> acc
end
end)
end
# Internal dispatcher for MCP add/update/remove actions
defp do_mcp_action(opts, :add, name) do
raw = build_server_config_from_opts(opts)
settings = Settings.new()
scope = if opts[:global], do: :global, else: :project
case Settings.MCP.add_server(settings, scope, name, raw) do
{:ok, upd} ->
%{name => Settings.MCP.list_servers(upd, scope)[name]}
|> Jason.encode!(pretty: true)
|> IO.puts()
{:error, :exists} ->
UI.error("Server '#{name}' already exists")
{:error, err} ->
UI.error(err)
end
end
defp do_mcp_action(opts, :update, name) do
raw = build_server_config_from_opts(opts)
settings = Settings.new()
scope = if opts[:global], do: :global, else: :project
case Settings.MCP.update_server(settings, scope, name, raw) do
{:ok, upd} ->
%{name => Settings.MCP.list_servers(upd, scope)[name]}
|> Jason.encode!(pretty: true)
|> IO.puts()
{:error, :not_found} ->
UI.error("Server '#{name}' not found")
{:error, err} ->
UI.error(err)
end
end
defp do_mcp_action(opts, :remove, name) do
settings = Settings.new()
scope = if opts[:global], do: :global, else: :project
case Settings.MCP.remove_server(settings, scope, name) do
{:ok, upd} ->
Settings.MCP.list_servers(upd, scope)
|> Jason.encode!(pretty: true)
|> IO.puts()
{:error, :not_found} ->
UI.error("Server '#{name}' not found")
end
end
end