///|
/// Check the restricted wire union, not arbitrary JSON Schema keywords.
/// Unknown fields remain available for extensions; runtime compilation decides
/// whether any additional validation keywords can actually be enforced.
fn check_elicitation_schema(value : Json) -> Unit raise MCPError {
let fields = wire_object(value)
guard fields.get("type") is Some(String("object")) else {
raise InvalidParams("Elicitation requestedSchema.type must be object")
}
ignore(wire_optional_string(fields, "$schema"))
ignore(wire_optional_strings(fields, "required"))
guard fields.get("properties") is Some(Object(properties)) else {
raise InvalidParams("Elicitation requestedSchema requires properties")
}
for _, property in properties {
check_elicitation_property(property)
}
}
///|
fn check_elicitation_property(value : Json) -> Unit raise MCPError {
let fields = wire_object(value)
ignore(wire_optional_string(fields, "title"))
ignore(wire_optional_string(fields, "description"))
match wire_string(fields, "type") {
"string" => {
ignore(wire_optional_string(fields, "default"))
ignore(wire_optional_number(fields, "minLength"))
ignore(wire_optional_number(fields, "maxLength"))
match wire_optional_string(fields, "format") {
None | Some("email" | "uri" | "date" | "date-time") => ()
Some(_) => raise InvalidParams("Invalid elicitation string format")
}
ignore(wire_optional_strings(fields, "enum"))
ignore(wire_optional_strings(fields, "enumNames"))
if fields.contains("oneOf") {
check_elicitation_options(fields, "oneOf")
}
}
"number" | "integer" => {
ignore(wire_optional_number(fields, "minimum"))
ignore(wire_optional_number(fields, "maximum"))
ignore(wire_optional_number(fields, "default"))
}
"boolean" => ignore(wire_optional_bool(fields, "default"))
"array" => {
ignore(wire_optional_number(fields, "minItems"))
ignore(wire_optional_number(fields, "maxItems"))
ignore(wire_optional_strings(fields, "default"))
guard fields.get("items") is Some(Object(items)) else {
raise InvalidParams("Elicitation multi-select requires items")
}
if items.contains("anyOf") {
check_elicitation_options(items, "anyOf")
} else {
guard items.get("type") is Some(String("string")) &&
wire_optional_strings(items, "enum") is Some(_) else {
raise InvalidParams(
"Elicitation multi-select requires string enum items",
)
}
}
}
_ =>
raise InvalidParams(
"Elicitation properties must be primitive or multi-select enums",
)
}
}
///|
fn check_elicitation_options(
fields : Map[String, Json],
keyword : String,
) -> Unit raise MCPError {
guard fields.get(keyword) is Some(Array(options)) else {
raise InvalidParams("Elicitation '" + keyword + "' must be an array")
}
for option in options {
let fields = wire_object(option)
ignore(wire_string(fields, "const"))
ignore(wire_string(fields, "title"))
}
}