Packages
fnord
0.8.29
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/services/MCP.ex.0.0.bak
defmodule Services.MCP do
@moduledoc false
alias MCP.Supervisor, as: MCPSup
alias Settings.MCP, as: MCPSettings
alias Services.Once
alias MCP.Tools
alias UI
alias Hermes.Client.Base, as: MCPBase
alias Hermes.MCP.Response
alias Hermes.MCP.Error
# Allow tests to override the client implementation via application env.
# Default to Hermes.Client.Base (direct client API) in production.
defp client_mod, do: Application.get_env(:fnord, :mcp_client_mod, MCPBase)
@spec start() :: :ok
def start do
cfg = MCPSettings.effective_config(Settings.new())
if cfg["enabled"] && map_size(cfg["servers"]) > 0 do
ensure_supervisor()
Once.run(:mcp_discovery, fn -> discover_once(cfg["servers"]) end)
end
:ok
end
defp ensure_supervisor do
case Process.whereis(MCPSup) do
nil -> MCPSup.start_link([])
_ -> :ok
end
:ok
end
defp discover_once(servers) when is_map(servers) do
Enum.each(servers, fn {server, cfg} ->
case safe_list_tools(server) do
{:ok, tools} ->
Tools.register_server_tools(server, tools)
{:error, reason} ->
UI.warn(
Jason.encode!(
%{
mcp_discovery_error: %{server: server, transport: cfg["transport"], error: reason}
},
pretty: true
)
)
end
end)
end
# Robustly list tools for a server, supporting both Hermes.Base and stubbed return shapes.
defp safe_list_tools(server) do
instance = MCPSup.instance_name(server)
try do
case client_mod().list_tools(instance) do
# Hermes.Base returns {:ok, Response.t()}
{:ok, %Response{} = resp} ->
result = Response.get_result(resp)
tools = Map.get(result, "tools", [])
{:ok, tools}
# Some stubs might return {:ok, list}
{:ok, tools} when is_list(tools) ->
{:ok, tools}
# Or {:ok, map} where map contains "tools"
{:ok, %{"tools" => tools}} when is_list(tools) ->
{:ok, tools}
{:error, %Error{reason: reason}} ->
{:error, reason}
{:error, reason} ->
{:error, reason}
end
catch
:exit, reason -> {:error, reason}
rescue
e -> {:error, Exception.message(e)}
end
end
@spec test() :: map()
def test do
cfg = MCPSettings.effective_config(Settings.new())
servers =
cfg["servers"]
|> Enum.map(fn {server, _} ->
info =
case safe_get_info(server) do
{:ok, _} -> %{status: "ok"}
{:error, reason} -> %{status: "error", error: reason}
end
tools =
case safe_list_tools(server) do
{:ok, tools} ->
%{status: "ok", tools: Enum.map(tools, &tool_blurb/1)}
{:error, reason} ->
%{status: "error", error: reason}
end
{server, Map.merge(info, tools)}
end)
|> Enum.into(%{})
%{status: "ok", servers: servers}
end
# Retrieve server info; Hermes.Base returns a map or nil, stubs may return {:ok, map} | {:error, reason}
defp safe_get_info(server) do
instance = MCPSup.instance_name(server)
case client_mod().get_server_info(instance) do
# Hermes.Base shape
%{} = info -> {:ok, info}
nil -> {:error, :not_initialized}
# Stubbed shapes
{:ok, %{} = info} -> {:ok, info}
{:error, %Error{reason: reason}} -> {:error, reason}
{:error, reason} -> {:error, reason}
end
end
@spec tool_blurb(tool :: map()) :: map()
defp tool_blurb(tool) do
%{"name" => tool["name"], "description" => Map.get(tool, "description", "")}
end
end