Class: ActionMCP::Server::ElicitationRequest

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Attributes, ActiveModel::Model
Defined in:
lib/action_mcp/server/elicitation_request.rb

Overview

Value object for form-mode elicitation requests. Validates that the requested schema follows MCP constraints: flat object with primitive properties only.

Constant Summary collapse

STRING_SCHEMA =
{
  "type" => "object",
  "required" => [ "type" ],
  "properties" => {
    "type" => { "const" => "string" },
    "title" => { "type" => "string" },
    "description" => { "type" => "string" },
    "default" => { "type" => "string" },
    "format" => { "enum" => %w[date date-time email uri] },
    "minLength" => { "type" => "integer" },
    "maxLength" => { "type" => "integer" }
  }
}.freeze
NUMBER_SCHEMA =
{
  "type" => "object",
  "required" => [ "type" ],
  "properties" => {
    "type" => { "enum" => %w[integer number] },
    "title" => { "type" => "string" },
    "description" => { "type" => "string" },
    "default" => { "type" => "integer" },
    "minimum" => { "type" => "integer" },
    "maximum" => { "type" => "integer" }
  }
}.freeze
BOOLEAN_SCHEMA =
{
  "type" => "object",
  "required" => [ "type" ],
  "properties" => {
    "type" => { "const" => "boolean" },
    "title" => { "type" => "string" },
    "description" => { "type" => "string" },
    "default" => { "type" => "boolean" }
  }
}.freeze
ENUM_OPTION_SCHEMA =
{
  "type" => "object",
  "required" => %w[const title],
  "properties" => {
    "const" => { "type" => "string" },
    "title" => { "type" => "string" }
  }
}.freeze
UNTITLED_MULTI_SELECT_SCHEMA =
{
  "type" => "object",
  "required" => %w[items type],
  "properties" => {
    "type" => { "const" => "array" },
    "title" => { "type" => "string" },
    "description" => { "type" => "string" },
    "default" => { "type" => "array", "items" => { "type" => "string" } },
    "minItems" => { "type" => "integer" },
    "maxItems" => { "type" => "integer" },
    "items" => {
      "type" => "object",
      "required" => %w[enum type],
      "properties" => {
        "type" => { "const" => "string" },
        "enum" => { "type" => "array", "items" => { "type" => "string" } }
      }
    }
  }
}.freeze
TITLED_MULTI_SELECT_SCHEMA =
{
  "type" => "object",
  "required" => %w[items type],
  "properties" => {
    "type" => { "const" => "array" },
    "title" => { "type" => "string" },
    "description" => { "type" => "string" },
    "default" => { "type" => "array", "items" => { "type" => "string" } },
    "minItems" => { "type" => "integer" },
    "maxItems" => { "type" => "integer" },
    "items" => {
      "type" => "object",
      "required" => [ "anyOf" ],
      "properties" => {
        "anyOf" => { "type" => "array", "items" => ENUM_OPTION_SCHEMA }
      }
    }
  }
}.freeze
REQUESTED_SCHEMA =
{
  "type" => "object",
  "required" => %w[properties type],
  "properties" => {
    "$schema" => { "type" => "string" },
    "type" => { "const" => "object" },
    "required" => { "type" => "array", "items" => { "type" => "string" } },
    "properties" => {
      "type" => "object",
      "additionalProperties" => {
        "anyOf" => [
          STRING_SCHEMA,
          NUMBER_SCHEMA,
          BOOLEAN_SCHEMA,
          UNTITLED_MULTI_SELECT_SCHEMA,
          TITLED_MULTI_SELECT_SCHEMA
        ]
      }
    }
  }
}.freeze
REQUESTED_SCHEMA_SCHEMER =
JSONSchemer.schema(REQUESTED_SCHEMA)
TASK_SCHEMA =
{
  "type" => "object",
  "additionalProperties" => false,
  "properties" => {
    "ttl" => { "type" => "integer" }
  }
}.freeze
TASK_SCHEMER =
JSONSchemer.schema(TASK_SCHEMA)

Instance Method Summary collapse

Instance Method Details

#assert_valid!Object

Validates and raises ArgumentError on failure (preserving public API). Named assert_valid! to avoid shadowing ActiveModel#validate!

Raises:

  • (ArgumentError)


159
160
161
162
163
# File 'lib/action_mcp/server/elicitation_request.rb', line 159

def assert_valid!
  return if valid?

  raise ArgumentError, errors.full_messages.join(", ")
end

#requested_schema=(value) ⇒ Object

Wrap incoming schema in indifferent access so both string and symbol keys work.



145
146
147
# File 'lib/action_mcp/server/elicitation_request.rb', line 145

def requested_schema=(value)
  super(value.is_a?(Hash) ? value.with_indifferent_access : value)
end

#to_paramsHash

Returns JSON-RPC params for elicitation/create.

Returns:

  • (Hash)

    JSON-RPC params for elicitation/create



150
151
152
153
154
155
# File 'lib/action_mcp/server/elicitation_request.rb', line 150

def to_params
  params = { mode: "form", message: message, requestedSchema: requested_schema.to_hash.deep_symbolize_keys }
  params[:_meta] = _meta if _meta.present?
  params[:task] = task unless task.nil?
  params
end