Define an MCP tool as a module.
defmodule MyApp.MCP.GetWeather do
use Noizu.MCP.Server.Tool,
description: "Get current weather for a location",
annotations: [read_only_hint: true]
input do
field :location, :string, required: true, description: "City name or zip"
field :units, :enum, values: [:celsius, :fahrenheit], default: :celsius
field :days, :integer, min: 1, max: 14, default: 1
end
output do
field :temperature, :number, required: true
field :conditions, :string, required: true
end
@impl true
# โฆ๐๐๐๐ฎโง call :: auto-generated pointer for public function call
def call(%{location: location, units: units, days: days}, ctx) do
Noizu.MCP.Ctx.report_progress(ctx, 0.5)
{:ok, %{temperature: 21.0, conditions: "clear"}}
end
enduse options
:nameโ wire name; defaults to the module basename underscored (MyApp.MCP.GetWeatherโ"get_weather"):descriptionโ tells the model when and why to use the tool. Accepts a plain string or a verbosity variant list (seeNoizu.MCP.Description):descriptionsโ named description variants ([tag: "text", ...]) referenced by:verbosity_map/:runners(spec ยง3):verbosity_mapโ[{verbosity_spec, tag}, ...]selecting a named variant by verbosity level:runnersโ[{{provider, model_matcher}, rules}, ...]selecting a named variant by{runner, model}(spec ยง3); seeNoizu.MCP.Description:titleโ human-readable display name:annotationsโ keyword list of behavior hints (:read_only_hint,:destructive_hint,:idempotent_hint,:open_world_hint,:title):icons,:metaโ passed through to the wire definition:hiddenโ whentrue, the tool is omitted fromtools/listresponses but remains callable. Useful for internal or privileged tools.:categoryโ free-form grouping label. Rides on the wire in_meta.category(merged into:meta) and is filterable through the built-inNoizu.MCP.Server.Tools.Catalogtool.:evalsโ a list of inline eval specs for description tuning (spec ยง4); each is[name: ..., prompt: ..., rubric: ...]. SeeNoizu.MCP.Eval. Evals are compile-time metadata for themix noizu.mcp.evalharness and never appear on the wire.
Need several small tools in one module? See Noizu.MCP.Server.Toolkit.
Schemas
input do ... end declares the input schema with the field DSL โ see the
Tools & Schemas guide for field types. Arguments are validated against the
compiled JSON Schema before call/2 runs (failures become isError: true
results the model can correct), then delivered atom-keyed with defaults
applied and :enum values cast to atoms.
Prefer raw JSON Schema? Use the escape hatch โ arguments are then validated but delivered string-keyed, uncast:
input_schema %{
"type" => "object",
"properties" => %{"query" => %{"type" => "string"}},
"required" => ["query"]
}input_schema/output_schema also accept the schema as raw JSON text
(decoded at compile time โ malformed JSON is a compile error):
input_schema """
{"type": "object", "properties": {"query": {"type": "string"}}, "required": ["query"]}
"""output do ... end (or output_schema %{...}) declares outputSchema; map
return values are validated against it and sent as structuredContent.
Return values from call/2
{:ok, String.t()}โ single text content block{:ok, map()}โ structured content (requires/uses output schema if declared){:ok, Content.t() | [Content.t()]}โ explicit content blocks{:ok, ToolResult.t()}โ full control{:error, String.t() | Content.t() | [Content.t()]}โ tool execution error (isError: true, visible to the model){:error, Noizu.MCP.Error.t()}โ protocol error
Summary
Callbacks
Normalized runtime descriptor(s) โ one-element list for classic tool modules.
Execute the tool. See the module docs for argument and return contracts.
The wire definition advertised by tools/list.
Functions
Declare the input schema with the field DSL.
Declare the input schema as a raw JSON Schema map (string keys).
Declare the output schema with the field DSL.
Declare the output schema as a raw JSON Schema map (string keys).
Callbacks
@callback __mcp_tools__() :: [Noizu.MCP.Server.Tool.Spec.t()]
Normalized runtime descriptor(s) โ one-element list for classic tool modules.
@callback call(args :: map(), ctx :: Noizu.MCP.Ctx.t()) :: {:ok, term()} | {:error, term()}
Execute the tool. See the module docs for argument and return contracts.
@callback definition() :: Noizu.MCP.Types.Tool.t()
The wire definition advertised by tools/list.
Functions
Declare the input schema with the field DSL.
Declare the input schema as a raw JSON Schema map (string keys).
Declare the output schema with the field DSL.
Declare the output schema as a raw JSON Schema map (string keys).