Hermes.Client (hermes_mcp v0.3.6)

A GenServer implementation of an MCP (Model Context Protocol) client.

This module handles the client-side implementation of the MCP protocol, including initialization, request/response handling, and maintaining protocol state.

Notes

For initialization and setup, check our Installation & Setup and the Client Usage guides for reference.

Summary

Types

MCP client capabilities

MCP client metadata info

MCP client initialization options

t()

MCP client transport options

Functions

Returns a specification to start this module under a supervisor.

Closes the client connection and terminates the process.

Gets a specific prompt from the server.

Gets the server's capabilities as reported during initialization.

Gets the server's information as reported during initialization.

Lists available prompts from the server.

Lists available resources from the server.

Lists available tools from the server.

Merges additional capabilities into the client's capabilities.

Sends a ping request to the server to check connection health. Returns :pong if successful.

Reads a specific resource from the server.

Registers a callback function to be called when log messages are received.

Registers a callback function to be called when progress notifications are received for the specified progress token.

Sends a progress notification to the server for a long-running operation.

Sets the minimum log level for the server to send log messages.

Starts a new MCP client process.

Unregisters a previously registered log callback.

Unregisters a previously registered progress callback for the specified token.

Types

capabilities()

@type capabilities() :: %{
  optional(:roots | String.t()) => %{
    optional(:listChanged | String.t()) => boolean()
  },
  optional(:sampling | String.t()) => %{}
}

MCP client capabilities

  • :roots - Capabilities related to the roots resource
    • :listChanged - Whether the client can handle listChanged notifications
  • :sampling - Capabilities related to sampling

MCP describes these client capabilities on it specification

client_info()

@type client_info() :: %{
  required(:name | String.t()) => String.t(),
  optional(:version | String.t()) => String.t()
}

MCP client metadata info

  • :name - The name of the client (required)
  • :version - The version of the client

option()

@type option() ::
  {:name, GenServer.name()}
  | {:transport, transport()}
  | {:client_info, map()}
  | {:capabilities, map()}
  | {:protocol_version, String.t()}
  | {:request_timeout, integer()}
  | GenServer.option()

MCP client initialization options

  • :name - Following the GenServer patterns described on "Name registration".
  • :transport - The MCP transport options
  • :client_info - Information about the client
  • :capabilities - Client capabilities to advertise to the MCP server
  • :protocol_version - Protocol version to use (defaults to "2024-11-05")
  • :request_timeout - Default timeout for requests in milliseconds (default: 30s)

Any other option support by GenServer.

t()

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

transport()

@type transport() :: [
  layer: Hermes.Transport.STDIO | Hermes.Transport.SSE,
  name: GenServer.server()
]

MCP client transport options

Functions

call_tool(client, name, arguments \\ nil, opts \\ [])

@spec call_tool(t(), String.t(), map() | nil, keyword()) ::
  {:ok, Hermes.MCP.Response.t()} | {:error, Hermes.MCP.Error.t()}

Calls a tool on the server.

Options

  • :timeout - Request timeout in milliseconds
  • :progress - Progress tracking options
    • :token - A unique token to track progress (string or integer)
    • :callback - A function to call when progress updates are received

cancel_all_requests(client, reason \\ "client_cancelled")

@spec cancel_all_requests(t(), String.t()) ::
  {:ok, [Hermes.Client.Request.t()]} | {:error, Hermes.MCP.Error.t()}

Cancels all pending requests.

Parameters

  • client - The client process
  • reason - Optional reason for cancellation (defaults to "client_cancelled")

Returns

  • {:ok, requests} - A list of the Request structs that were cancelled
  • {:error, reason} - If an error occurred

cancel_request(client, request_id, reason \\ "client_cancelled")

@spec cancel_request(t(), String.t(), String.t()) ::
  :ok | {:error, Hermes.MCP.Error.t()}

Cancels an in-progress request.

Parameters

  • client - The client process
  • request_id - The ID of the request to cancel
  • reason - Optional reason for cancellation

Returns

  • :ok if the cancellation was successful
  • {:error, reason} if an error occurred
  • {:not_found, request_id} if the request ID was not found

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

close(client)

@spec close(t()) :: :ok

Closes the client connection and terminates the process.

get_prompt(client, name, arguments \\ nil, opts \\ [])

@spec get_prompt(t(), String.t(), map() | nil, keyword()) ::
  {:ok, Hermes.MCP.Response.t()} | {:error, Hermes.MCP.Error.t()}

Gets a specific prompt from the server.

Options

  • :timeout - Request timeout in milliseconds
  • :progress - Progress tracking options
    • :token - A unique token to track progress (string or integer)
    • :callback - A function to call when progress updates are received

get_schema(atom)

get_server_capabilities(client)

@spec get_server_capabilities(t()) :: map() | nil

Gets the server's capabilities as reported during initialization.

Returns nil if the client has not been initialized yet.

get_server_info(client)

@spec get_server_info(t()) :: map() | nil

Gets the server's information as reported during initialization.

Returns nil if the client has not been initialized yet.

list_prompts(client, opts \\ [])

@spec list_prompts(
  t(),
  keyword()
) :: {:ok, Hermes.MCP.Response.t()} | {:error, Hermes.MCP.Error.t()}

Lists available prompts from the server.

Options

  • :cursor - Pagination cursor for continuing a previous request
  • :timeout - Request timeout in milliseconds
  • :progress - Progress tracking options
    • :token - A unique token to track progress (string or integer)
    • :callback - A function to call when progress updates are received

list_resources(client, opts \\ [])

@spec list_resources(
  t(),
  keyword()
) :: {:ok, Hermes.MCP.Response.t()} | {:error, Hermes.MCP.Error.t()}

Lists available resources from the server.

Options

  • :cursor - Pagination cursor for continuing a previous request
  • :timeout - Request timeout in milliseconds
  • :progress - Progress tracking options
    • :token - A unique token to track progress (string or integer)
    • :callback - A function to call when progress updates are received

list_tools(client, opts \\ [])

@spec list_tools(
  t(),
  keyword()
) :: {:ok, Hermes.MCP.Response.t()} | {:error, Hermes.MCP.Error.t()}

Lists available tools from the server.

Options

  • :cursor - Pagination cursor for continuing a previous request
  • :timeout - Request timeout in milliseconds
  • :progress - Progress tracking options
    • :token - A unique token to track progress (string or integer)
    • :callback - A function to call when progress updates are received

merge_capabilities(client, additional_capabilities)

@spec merge_capabilities(t(), map()) :: map()

Merges additional capabilities into the client's capabilities.

parse_options(data)

parse_options!(data)

ping(client, opts \\ [])

@spec ping(
  t(),
  keyword()
) :: :pong | {:error, Hermes.MCP.Error.t()}

Sends a ping request to the server to check connection health. Returns :pong if successful.

read_resource(client, uri, opts \\ [])

@spec read_resource(t(), String.t(), keyword()) ::
  {:ok, Hermes.MCP.Response.t()} | {:error, Hermes.MCP.Error.t()}

Reads a specific resource from the server.

Options

  • :timeout - Request timeout in milliseconds
  • :progress - Progress tracking options
    • :token - A unique token to track progress (string or integer)
    • :callback - A function to call when progress updates are received

register_log_callback(client, callback)

@spec register_log_callback(t(), Hermes.Client.State.log_callback()) :: :ok

Registers a callback function to be called when log messages are received.

Parameters

  • client - The client process
  • callback - A function that takes three arguments: level, data, and logger name

The callback function will be called whenever a log message notification is received.

register_progress_callback(client, progress_token, callback)

@spec register_progress_callback(
  t(),
  String.t() | integer(),
  Hermes.Client.State.progress_callback()
) :: :ok

Registers a callback function to be called when progress notifications are received for the specified progress token.

Parameters

  • client - The client process
  • progress_token - The progress token to watch for (string or integer)
  • callback - A function that takes three arguments: progress_token, progress, and total

The callback function will be called whenever a progress notification with the matching token is received.

send_progress(client, progress_token, progress, total \\ nil)

@spec send_progress(t(), String.t() | integer(), number(), number() | nil) ::
  :ok | {:error, term()}

Sends a progress notification to the server for a long-running operation.

Parameters

  • client - The client process
  • progress_token - The progress token provided in the original request (string or integer)
  • progress - The current progress value (number)
  • total - The optional total value for the operation (number)

Returns :ok if notification was sent successfully, or {:error, reason} otherwise.

set_log_level(client, level)

@spec set_log_level(t(), String.t()) ::
  {:ok, Hermes.MCP.Response.t()} | {:error, Hermes.MCP.Error.t()}

Sets the minimum log level for the server to send log messages.

Parameters

  • client - The client process
  • level - The minimum log level (debug, info, notice, warning, error, critical, alert, emergency)

Returns {:ok, result} if successful, {:error, reason} otherwise.

start_link(opts)

@spec start_link(Enumerable.t(option())) :: GenServer.on_start()

Starts a new MCP client process.

unregister_log_callback(client)

@spec unregister_log_callback(t()) :: :ok

Unregisters a previously registered log callback.

Parameters

  • client - The client process
  • callback - The callback function to unregister

unregister_progress_callback(client, progress_token)

@spec unregister_progress_callback(t(), String.t() | integer()) :: :ok

Unregisters a previously registered progress callback for the specified token.

Parameters

  • client - The client process
  • progress_token - The progress token to stop watching (string or integer)