Excessibility.MCP.Elicitation (Excessibility v0.14.0)

View Source

Handles the MCP elicitation protocol for structured user interaction.

Elicitation allows MCP tools to pause execution and ask the user a structured question. The server sends an elicitation/create request to the client, which presents the question and returns the user's response.

Usage in Tools

Tools receive an elicit callback via their opts when the server supports elicitation:

def execute(args, opts) do
  case opts[:elicit] do
    nil ->
      # No elicitation support, proceed with defaults
      do_work(args)

    elicit ->
      schema = %{
        "type" => "object",
        "properties" => %{
          "approved" => %{"type" => "boolean", "description" => "Approve this action?"}
        }
      }

      case elicit.("Found 5 issues. Fix them?", schema) do
        {:accept, %{"approved" => true}} -> fix_issues(args)
        {:accept, _} -> {:ok, %{"status" => "skipped"}}
        :decline -> {:ok, %{"status" => "declined"}}
        :cancel -> {:error, "cancelled by user"}
      end
  end
end

Protocol

The elicitation flow follows JSON-RPC 2.0:

  1. Server sends elicitation/create request with message and schema
  2. Client responds with {action: "accept"|"decline"|"cancel", content: {...}}

Summary

Functions

Builds an elicitation callback function for use in tool opts.

Builds a JSON-RPC 2.0 elicitation request.

Parses a JSON-RPC elicitation response.

Functions

build_callback(write_fn, read_fn)

@spec build_callback((String.t() -> :ok) | nil, (-> String.t()) | nil) ::
  (String.t(), map() ->
     {:accept, map()} | :decline | :cancel | {:error, term()})
  | nil

Builds an elicitation callback function for use in tool opts.

Returns nil if either write_fn or read_fn is nil (elicitation not supported). Otherwise returns a 2-arity function fn message, schema -> result that handles the full elicitation round-trip: building the request, writing it as JSON, reading the response, and parsing it.

Parameters

  • write_fn - A 1-arity function that writes a string to the client
  • read_fn - A 0-arity function that reads a string response from the client

build_request(id, message, requested_schema)

@spec build_request(integer(), String.t(), map()) :: map()

Builds a JSON-RPC 2.0 elicitation request.

Returns a map with method "elicitation/create" and params containing the message and requested schema.

parse_response(arg1)

@spec parse_response(map()) ::
  {:accept, map()} | :decline | :cancel | {:error, term()}

Parses a JSON-RPC elicitation response.

Returns:

  • {:accept, content} when the user accepted and provided content
  • :decline when the user declined
  • :cancel when the user cancelled