Converts DSL parameter definitions to NimbleOptions validation schemas.
This module takes parameter definitions from the ConduitMCP DSL and converts them into NimbleOptions schemas for runtime validation. It handles type mapping, constraint extraction, and validation rule compilation.
Type Mapping
DSL types are mapped to NimbleOptions types as follows:
:string->:string:integer->:integer:number->:number(float):boolean->:boolean:object->{:map, :any, :any}for an open object (no declared fields);:mapwith a nestedkeys:schema when nested fields are declared:array->{:list, type}where type is the item type{:array, item_type}->{:list, converted_item_type}
Validation Options
DSL options are converted to NimbleOptions validation rules:
required: true->required: trueenum: [...]->in: [...]default: value->default: valuemin: value->min: valuemax: value->max: valuemin_length: value->min_length: valuemax_length: value->max_length: valuevalidator: function->validator: function
Nested Objects
An :object param that declares nested fields is converted to
type: :map, keys: [...], built by recursing through this same function, so
nesting works to any depth and NimbleOptions reports errors with a key path
(in options [:bag, :inner]).
Undeclared keys in such an object are rejected unless the param carries
additional_properties: true. An object with no declared fields is an open
bag: {:map, :any, :any}, anything accepted.
Nested keys arrive as strings over JSON-RPC and NimbleOptions' nested
validation is atom-key-only, so ConduitMcp.Validation atomises nested keys
before validating — but only those matching a declared field name, which
are already interned at compile time. Client input never mints an atom.
Enforcement boundary
Nested validation covers :object params and objects nested inside them.
It does not cover objects inside :array items: NimbleOptions has no
way to attach a keys: schema to a list element type. Item schemas declared
with items :object do ... end are published in the JSON Schema for clients
but are not enforced server-side beyond {:list, :any}.
Summary
Functions
Compiles a complete tool definition to a NimbleOptions validation schema.
Converts a list of DSL parameter definitions to a NimbleOptions schema.
Enhanced error formatter for NimbleOptions validation errors.
Strips custom constraint markers from a schema, recursing through nested
keys: schemas.
Validates a NimbleOptions schema definition.
Functions
Compiles a complete tool definition to a NimbleOptions validation schema.
Takes a tool definition with parameters and converts it to a schema that can be used for runtime validation.
Converts a list of DSL parameter definitions to a NimbleOptions schema.
Examples
iex> params = [
...> %{name: :name, type: :string, opts: [required: true]},
...> %{name: :age, type: :integer, opts: [min: 0, max: 150]}
...> ]
iex> ConduitMcp.Validation.SchemaConverter.dsl_params_to_nimble_options(params)
[
name: [type: :string, required: true],
age: [type: :integer, min: 0, max: 150]
]
Enhanced error formatter for NimbleOptions validation errors.
Takes a NimbleOptions.ValidationError and converts it to detailed error information suitable for MCP responses.
Strips custom constraint markers from a schema, recursing through nested
keys: schemas.
The markers carry constraints NimbleOptions has no native option for
(enum, min/max, length limits, custom validators) plus the
additional_properties knob. They ride alongside the real options in the
full schema and must be removed before it reaches NimbleOptions, which
rejects unknown option keys — including inside a nested keys: schema.
Single source of truth. Used by ConduitMcp.Validation,
ConduitMcp.DSL.SchemaBuilder, and ConduitMcp.Endpoint.
Validates a NimbleOptions schema definition.
Checks if the generated schema is valid for NimbleOptions. Used during compile time to catch schema generation errors.