Packages
fnord
0.9.40
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/mcp/client.ex
defmodule MCP.Client do
@moduledoc """
Facade for the Hermes MCP client runtime: the VM-global `MCP.Supervisor`
and the per-server Hermes client GenServers it supervises.
Every Hermes touch point in fnord routes through this module so tests can
substitute a `Mox` double (`Fnord.TestCase.mock_mcp_client/0`) instead of
booting real server transports. The real implementation lives in
`MCP.Client.Default`.
Callbacks are keyed by *server name* (the key in `Settings.MCP` config),
not by client pid or atom - resolving the registered process for a server
is an implementation detail of the runtime.
"""
@doc """
Starts the MCP supervisor (idempotent) and detaches it from the caller.
The Hermes stack is VM-global and must outlive the process that happened
to trigger it; see `MCP.Client.Default` for the unlink rationale.
"""
@callback start_supervisor() :: :ok | {:error, term()}
@doc "True when the server's client process is registered and alive."
@callback connected?(server :: String.t()) :: boolean()
@doc "Lists the tools advertised by a connected server."
@callback list_tools(server :: String.t()) :: {:ok, [map()]} | {:error, term()}
@doc "Fetches the capabilities map negotiated with a connected server."
@callback get_server_capabilities(server :: String.t()) :: {:ok, map()} | {:error, term()}
@doc "Invokes a tool on a connected server, returning the unwrapped result."
@callback call_tool(server :: String.t(), tool :: String.t(), args :: map(), opts :: keyword()) ::
{:ok, term()} | {:error, term()}
def impl() do
Services.Globals.get_env(:fnord, :mcp_client, MCP.Client.Default)
end
@spec start_supervisor() :: :ok | {:error, term()}
def start_supervisor(), do: impl().start_supervisor()
@spec connected?(String.t()) :: boolean()
def connected?(server), do: impl().connected?(server)
@spec list_tools(String.t()) :: {:ok, [map()]} | {:error, term()}
def list_tools(server), do: impl().list_tools(server)
@spec get_server_capabilities(String.t()) :: {:ok, map()} | {:error, term()}
def get_server_capabilities(server), do: impl().get_server_capabilities(server)
@spec call_tool(String.t(), String.t(), map(), keyword()) :: {:ok, term()} | {:error, term()}
def call_tool(server, tool, args, opts), do: impl().call_tool(server, tool, args, opts)
end