Hermolaos.Client.Connection (Hermolaos v0.3.0)

View Source

GenServer managing a single MCP connection.

The Connection is the core component of the Hermolaos client. It manages:

  • Transport lifecycle (stdio or HTTP)
  • Protocol initialization handshake
  • Request/response correlation
  • Server notification handling
  • Connection state machine

State Machine

:disconnected --> :connecting --> :initializing --> :ready
      ^              |                |               |
      |              v                v               v
      +------------- (error) --------+---------------+

Usage

Typically, you don't interact with Connection directly. Use the Hermolaos module for a higher-level API.

Example

{:ok, conn} = Hermolaos.Client.Connection.start_link(
  transport: :stdio,
  command: "npx",
  args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
)

{:ok, tools} = Hermolaos.Client.Connection.request(conn, "tools/list", %{})

Summary

Functions

Returns a specification to start this module under a supervisor.

Disconnects from the server.

Sends a notification (no response expected).

Sends a request and waits for a response.

Gets server capabilities from the initialization response.

Gets server information from the initialization response.

Starts a new MCP connection.

Gets the current connection status.

Types

option()

@type option() ::
  {:transport, transport_type()}
  | {:command, String.t()}
  | {:args, [String.t()]}
  | {:url, String.t()}
  | {:headers, [{String.t(), String.t()}]}
  | {:client_info, map()}
  | {:capabilities, map()}
  | {:notification_handler, module() | {module(), term()}}
  | {:timeout, pos_integer()}
  | {:name, GenServer.name()}

state()

@type state() :: %{
  status: status(),
  transport_type: transport_type(),
  transport_mod: module(),
  transport_pid: pid() | nil,
  transport_opts: keyword(),
  tracker_pid: pid() | nil,
  server_info: map() | nil,
  server_capabilities: map() | nil,
  client_capabilities: map(),
  client_info: map(),
  protocol_version: String.t() | nil,
  notification_handler: module() | {module(), term()} | nil,
  pending_init: GenServer.from() | nil,
  default_timeout: pos_integer()
}

status()

@type status() :: :disconnected | :connecting | :initializing | :ready

t()

@type t() :: GenServer.server()

transport_type()

@type transport_type() :: :stdio | :http

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

disconnect(conn)

@spec disconnect(t()) :: :ok

Disconnects from the server.

notify(conn, method, params)

@spec notify(t(), String.t(), map()) :: :ok | {:error, term()}

Sends a notification (no response expected).

Parameters

  • conn - The connection process
  • method - JSON-RPC method name
  • params - Notification parameters

Examples

:ok = Hermolaos.Client.Connection.notify(conn, "notifications/cancelled", %{requestId: 1})

request(conn, method, params, opts \\ [])

@spec request(t(), String.t(), map(), keyword()) :: {:ok, map()} | {:error, term()}

Sends a request and waits for a response.

Parameters

  • conn - The connection process
  • method - JSON-RPC method name
  • params - Request parameters
  • opts - Options:
    • :timeout - Override default timeout

Returns

  • {:ok, result} - Success with result map
  • {:error, reason} - Error occurred

Examples

{:ok, %{"tools" => tools}} = Hermolaos.Client.Connection.request(conn, "tools/list", %{})

server_capabilities(conn)

@spec server_capabilities(t()) :: {:ok, map()} | {:error, :not_initialized}

Gets server capabilities from the initialization response.

server_info(conn)

@spec server_info(t()) :: {:ok, map()} | {:error, :not_initialized}

Gets server information from the initialization response.

start_link(opts)

@spec start_link(keyword()) :: {:ok, pid()} | {:error, term()}

Starts a new MCP connection.

Options

Transport Options (one required)

For stdio transport:

  • :transport - Set to :stdio
  • :command - Command to execute (required)
  • :args - Command arguments (default: [])

For HTTP transport:

  • :transport - Set to :http
  • :url - Server URL (required)
  • :headers - Additional HTTP headers (default: [])

Common Options

  • :client_info - Client identification (default: Hermolaos info)
  • :capabilities - Client capabilities (default: standard capabilities)
  • :notification_handler - Module or {module, state} for handling notifications
  • :timeout - Default request timeout in ms (default: 30000)
  • :name - GenServer name (optional)

Examples

# Stdio transport
{:ok, conn} = Hermolaos.Client.Connection.start_link(
  transport: :stdio,
  command: "/usr/bin/python3",
  args: ["-m", "my_mcp_server"]
)

# HTTP transport
{:ok, conn} = Hermolaos.Client.Connection.start_link(
  transport: :http,
  url: "http://localhost:3000/mcp"
)

status(conn)

@spec status(t()) :: status()

Gets the current connection status.

Returns

  • :disconnected - Not connected
  • :connecting - Transport starting
  • :initializing - Performing MCP handshake
  • :ready - Ready for requests