Noizu.MCP.Server.Tool behaviour (Noizu MCP v0.1.3)

Copy Markdown View Source

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
  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
end

use 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
  • :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 — when true, the tool is omitted from tools/list responses 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-in Noizu.MCP.Server.Tools.Catalog tool.

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

__mcp_tools__()

@callback __mcp_tools__() :: [Noizu.MCP.Server.Tool.Spec.t()]

Normalized runtime descriptor(s) — one-element list for classic tool modules.

call(args, ctx)

@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.

definition()

@callback definition() :: Noizu.MCP.Types.Tool.t()

The wire definition advertised by tools/list.

Functions

input(list)

(macro)

Declare the input schema with the field DSL.

input_schema(schema)

(macro)

Declare the input schema as a raw JSON Schema map (string keys).

output(list)

(macro)

Declare the output schema with the field DSL.

output_schema(schema)

(macro)

Declare the output schema as a raw JSON Schema map (string keys).