BB.MCP.PeriSchema (bb_mcp v0.1.0)

Copy Markdown View Source

Converts BB command argument definitions into Peri schemas suitable for Anubis.Server.Frame.register_tool/3.

Anubis takes the Peri schema we hand it, validates incoming tool calls against it, and re-renders it as JSON Schema on the wire. So one conversion suffices for both validation and discovery.

BB types map to Peri types as follows:

:integer | :pos_integer | :non_neg_integer -> :integer
:float | :number                           -> :float
:string                                    -> :string
:boolean                                   -> :boolean
:atom                                      -> :atom
:map | {:map, fields}                     -> :map
:keyword_list                              -> :keyword
:any                                       -> :any
module / unknown                           -> :any

Summary

Functions

Pre-process incoming params before Peri validation.

Build a Peri field value for a single argument, applying required and default wrappers and a description meta tag where set.

Build a Peri schema (map keyed by argument name) for a command's arguments.

Translate MCP-visible command params back to the command's original BB goal.

Functions

flatten_nested_params(command, params)

@spec flatten_nested_params(BB.Dsl.Command.t(), map()) :: map()

Pre-process incoming params before Peri validation.

Some MCP clients interpret a flat property name like "target.x" as a nested path and send %{"target" => %{"x" => ...}} instead of %{"target.x" => ...}. We advertise the flat (dotted) form deliberately — nested object schemas are poorly supported by some clients — so we flatten any nested object back to the dotted form here before Peri's schema validator sees them.

Also coerces JSON whole numbers (0, 1) to floats for fields whose schema type is :float — JSON has no syntactic distinction between integer and float zero, but Peri's :float validator rejects integers.

for_argument(argument)

@spec for_argument(BB.Dsl.Command.Argument.t()) :: term()

Build a Peri field value for a single argument, applying required and default wrappers and a description meta tag where set.

for_command(command)

@spec for_command(BB.Dsl.Command.t()) :: map()

Build a Peri schema (map keyed by argument name) for a command's arguments.

to_goal(command, params)

@spec to_goal(BB.Dsl.Command.t(), map()) :: map()

Translate MCP-visible command params back to the command's original BB goal.