Hermes.Server.Component.Tool behaviour (hermes_mcp v0.9.0)

Defines the behaviour for MCP tools.

Tools are functions that can be invoked by the client with specific parameters. Each tool must define its name, description, and parameter schema, as well as implement the execution logic.

Example

defmodule MyServer.Tools.Calculator do
  @behaviour Hermes.Server.Behaviour.Tool

  alias Hermes.Server.Frame

  @impl true
  def name, do: "calculator"

  @impl true
  def description, do: "Performs basic arithmetic operations"

  @impl true
  def input_schema do
    %{
      "type" => "object",
      "properties" => %{
        "operation" => %{
          "type" => "string",
          "enum" => ["add", "subtract", "multiply", "divide"]
        },
        "a" => %{"type" => "number"},
        "b" => %{"type" => "number"}
      },
      "required" => ["operation", "a", "b"]
    }
  end

  @impl true
  def execute(%{"operation" => "add", "a" => a, "b" => b}, frame) do
    result = a + b

    # Can access frame assigns
    user_id = frame.assigns[:user_id]

    # Can return updated frame if needed
    new_frame = Frame.assign(frame, :last_calculation, result)

    {:ok, result, new_frame}
  end

  @impl true
  def execute(%{"operation" => "divide", "a" => a, "b" => 0}, _frame) do
    {:error, "Cannot divide by zero"}
  end
end

Summary

Callbacks

Executes the tool with the given parameters.

Returns the JSON Schema for the tool's input parameters.

Functions

Validates that a module implements the Tool behaviour.

Converts a tool module into the MCP protocol format.

Types

params()

@type params() :: map()

result()

@type result() :: term()

schema()

@type schema() :: map()

Callbacks

execute(params, frame)

@callback execute(params :: params(), frame :: Hermes.Server.Frame.t()) ::
  {:reply, response :: Hermes.Server.Response.t(),
   new_state :: Hermes.Server.Frame.t()}
  | {:noreply, new_state :: Hermes.Server.Frame.t()}
  | {:error, error :: Hermes.MCP.Error.t(),
     new_state :: Hermes.Server.Frame.t()}

Executes the tool with the given parameters.

Parameters

  • params - The validated input parameters from the client
  • frame - The server frame containing:
    • assigns - Custom data like session_id, client_info, user permissions
    • initialized - Whether the server has been initialized

Return Values

  • {:ok, result} - Tool executed successfully, frame unchanged
  • {:ok, result, new_frame} - Tool executed successfully with frame updates
  • {:error, reason} - Tool failed with the given reason

Frame Usage

The frame provides access to server state and context:

def execute(params, frame) do
  # Access assigns
  user_id = frame.assigns[:user_id]
  permissions = frame.assigns[:permissions]

  # Update frame if needed
  new_frame = Frame.assign(frame, :last_tool_call, DateTime.utc_now())

  {:ok, "Result", new_frame}
end

input_schema()

@callback input_schema() :: schema()

Returns the JSON Schema for the tool's input parameters.

This schema is used to validate client requests and generate documentation. The schema should follow the JSON Schema specification.

Functions

implements?(module)

@spec implements?(module()) :: boolean()

Validates that a module implements the Tool behaviour.

to_protocol(tool_module)

@spec to_protocol(module()) :: map()

Converts a tool module into the MCP protocol format.