ExMCP.Server.HandlerServer (ex_mcp v1.0.0-rc.6)

Copy Markdown View Source

Transport-aware process for ExMCP.Server.Handler modules.

This module runs a handler module behind the MCP transports that need a server process, including the in-memory test transport.

Usage

# Handler module implementing ExMCP.Server.Handler
defmodule MyHandler do
  use ExMCP.Server.Handler

  @impl true
  def handle_initialize(params, state) do
    {:ok, %{
      protocolVersion: "2025-03-26",
      serverInfo: %{name: "test-server", version: "1.0.0"},
      capabilities: %{tools: %{}}
    }, state}
  end

  @impl true
  def handle_list_tools(_cursor, state) do
    tools = [
      %{
        name: "ping",
        description: "Simple ping tool",
        inputSchema: %{type: "object", properties: %{}}
      }
    ]
    {:ok, tools, nil, state}
  end
end

# Start the server
{:ok, server} = ExMCP.Server.HandlerServer.start_link(transport: :test, handler: MyHandler)

Summary

Functions

Returns a specification to start this module under a supervisor.

Starts a handler-based server.

Types

handler_module()

@type handler_module() :: module()

state()

@type state() :: %{
  handler_module: handler_module(),
  handler_state: any(),
  transport: any(),
  transport_state: any(),
  protocol_version: String.t() | nil,
  protocol_mode: ExMCP.Types.protocol_mode() | nil,
  connection_era: :legacy | :modern | nil,
  instructions: String.t() | nil,
  request_state: keyword() | nil,
  endpoint: String.t() | nil,
  principal_id: String.t() | nil,
  tenant_id: String.t() | nil,
  replay_cache: module() | {module(), keyword()} | nil,
  require_replay_protection: boolean(),
  pending_requests: map(),
  cancelled_requests: MapSet.t(),
  cancellation_tracker: module(),
  subscriptions: map(),
  subscription_options: keyword()
}

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start_link(opts)

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

Starts a handler-based server.

Options