Hermes.Server.Session (hermes_mcp v0.9.0)

Manages state for the Hermes MCP server base implementation.

This module provides a structured representation of server state during the MCP lifecycle, including initialization status, protocol negotiation, and server capabilities.

State Structure

Each server state includes:

  • protocol_version: Negotiated MCP protocol version
  • frame: Server frame (similar to LiveView socket)
  • initialized: Whether the server has completed initialization
  • client_info: Client information received during initialization
  • client_capabilities: Client capabilities received during initialization

Summary

Functions

Returns a specification to start this module under a supervisor.

Retrieves the current state of a session.

Guard to check if a session has been initialized.

Marks the session as initialized.

Creates a new server state with the given options.

Updates the log level.

Starts a new session agent with initial state.

Updates state after successful initialization handshake.

Types

t()

@type t() :: %Hermes.Server.Session{
  client_capabilities: map() | nil,
  client_info: map() | nil,
  id: String.t() | nil,
  initialized: boolean(),
  log_level: String.t(),
  name: GenServer.name() | nil,
  protocol_version: String.t() | nil
}

Functions

child_spec(arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

get(session)

@spec get(GenServer.name()) :: t()

Retrieves the current state of a session.

Parameters

  • session - The session agent name or PID

Returns

The current session state as a %Session{} struct.

Examples

iex> session_state = Session.get(session_name)
%Session{initialized: true, protocol_version: "2025-03-26"}

is_initialized(session)

(macro)

Guard to check if a session has been initialized.

Examples

iex> session = %Session{initialized: true}
iex> is_initialized(session)
true

mark_initialized(session)

@spec mark_initialized(GenServer.name()) :: :ok

Marks the session as initialized.

new(opts)

@spec new(Enumerable.t()) :: t()

Creates a new server state with the given options.

Parameters

  • opts - Map containing the initialization options

set_log_level(session, level)

@spec set_log_level(GenServer.name(), String.t()) :: :ok

Updates the log level.

start_link(opts \\ [])

@spec start_link(keyword()) :: Agent.on_start()

Starts a new session agent with initial state.

update_from_initialization(session, negotiated_version, client_info, capabilities)

@spec update_from_initialization(GenServer.name(), String.t(), map(), map()) :: :ok

Updates state after successful initialization handshake.

This function:

  1. Sets the negotiated protocol version
  2. Stores client information and capabilities
  3. Marks the server as initialized

Parameters

  • state - The current server state
  • protocol_version - The negotiated protocol version
  • client_info - Client information from the initialize request
  • client_capabilities - Client capabilities from the initialize request

Examples

iex> client_info = %{"name" => "hello", "version" => "1.0.0"}
iex> capabilities = %{"sampling" => %{}}
iex> Hermes.Server.Session.update_from_initialization(session, "2025-03-26", client_info, capabilities)
:ok