Tools feature plumbing: the helpers behind the generated
handle_list_tools/2 and handle_call_tool/3 defaults.
Most servers never call this module directly. Reach for it when you hand-write those callbacks but still want the registry-driven behavior — e.g. session-gated visibility:
@impl true
def handle_list_tools(cursor, ctx) do
Noizu.MCP.Server.Features.Tools.list_registered(
__mcp__(:tools),
cursor,
include_hidden: ctx.assigns[:unlocked] == true
)
endFor finer control, expand/1 flattens the __mcp__(:tools) registration
list into normalized Noizu.MCP.Server.Tool.Spec structs you can filter or
remap before building the response.
Also handled here: pagination, JSON Schema validation (per SEP-1303,
input-validation failures are isError execution results, not protocol
errors), argument casting for DSL tools, and normalization of handler
return values to wire maps.
Summary
Functions
Default handle_call_tool: dispatch to a registered tool spec.
Expand a [{module, opts}] registration list into flat [%Spec{}].
Default handle_list_tools over the registered tool modules.
Normalize a tool handler return value to a ToolResult.
Functions
Default handle_call_tool: dispatch to a registered tool spec.
Expand a [{module, opts}] registration list into flat [%Spec{}].
Every tool module exports __mcp_tools__/0 — classic
use Noizu.MCP.Server.Tool modules yield one spec,
use Noizu.MCP.Server.Toolkit modules yield one per @mcp-annotated
function. Registration opts are applied per spec:
:hidden/:visible— override visibility (visible: false≡hidden: true; an explicit:hiddenkey wins when both are given):category— merged into the definition'smetaas"category":name/:description— definition overrides, single-tool modules only (raisesArgumentErrorfor multi-tool registrations, where the override would be ambiguous)
Default handle_list_tools over the registered tool modules.
Normalize a tool handler return value to a ToolResult.