Shared logic used by the per-tool component modules under
BB.MCP.Tools.*.
Tools take a robot argument that selects which configured robot module
they operate on. The list of configured robots is read from
Application.get_env(:bb_mcp, :robots, []).
Summary
Functions
Comma-separated list of configured robot names, for error messages.
The commands declared on a robot.
Describe a command for the list_commands tool and the commands resource.
Resolve a robot argument from tool params to a robot module.
Fetch a tool argument from string-keyed or atom-keyed params.
Parse a parameter path string ("motion.max_speed") into atoms.
Schema fragment for the robot argument, shared by every tool.
Read the configured robots map.
Convert any failure value into an Anubis.MCP.Error for the JSON-RPC reply.
Functions
@spec available_names() :: String.t()
Comma-separated list of configured robot names, for error messages.
@spec commands(module()) :: [BB.Dsl.Command.t()]
The commands declared on a robot.
BB.Dsl.Info.commands/1 returns every entity in the DSL's commands
section, which holds command categories alongside the commands themselves,
so the categories are filtered out here.
@spec describe_command(BB.Dsl.Command.t()) :: map()
Describe a command for the list_commands tool and the commands resource.
Resolve a robot argument from tool params to a robot module.
Returns {:ok, module} or {:error, Anubis.MCP.Error.t()}.
Fetch a tool argument from string-keyed or atom-keyed params.
Parse a parameter path string ("motion.max_speed") into atoms.
Uses String.to_existing_atom/1: the path segments of a registered
parameter are already atoms, and a segment that isn't names a parameter that
cannot exist. Interning whatever an MCP client sends would let a remote
caller grow the atom table, which is never collected.
@spec robot_arg_schema() :: map()
Schema fragment for the robot argument, shared by every tool.
@spec robots() :: BB.MCP.Robots.config()
Read the configured robots map.
@spec to_anubis_error(term()) :: Anubis.MCP.Error.t()
Convert any failure value into an Anubis.MCP.Error for the JSON-RPC reply.
BB.Error (Splode) exceptions are rendered via Exception.message/1 with
their user-declared fields exposed under data, so MCP clients see the
actual reason (e.g. "Robot is in state :armed, requires one of: :disarmed")
instead of a generic "Internal error". Anubis errors pass through unchanged.