Define an MCP server.
defmodule MyApp.MCP do
use Noizu.MCP.Server,
name: "myapp",
version: "1.0.0",
instructions: "Weather and reporting tools for MyApp."
tool MyApp.MCP.GetWeather
tool MyApp.MCP.SendEmail, name: "send_email_v2"
resource MyApp.MCP.Config
resource_template MyApp.MCP.TableSchema
prompt MyApp.MCP.CodeReview
enduse Noizu.MCP.Server makes the module a supervisable child
(children = [{MyApp.MCP, transport: :stdio}]), registers components
declared with tool/2, resource/2, resource_template/2, and prompt/2,
derives the server's capabilities automatically, and provides notification
helpers:
MyApp.MCP.notify_changed(:tools) # list-changed fan-out
MyApp.MCP.notify_resource_updated("config://app") # to subscribed sessionsuse options
:name(required) — server name advertised inserverInfo:version(required) — server version string:title,:description,:website_url,:icons— optionalserverInfometadata:instructions— usage hints delivered to the client on initialize
Escape hatch: behaviours without macros
Everything the DSL generates is an implementation of this module's
behaviour. Skip the component registrations and implement the handle_*
callbacks directly; implementing a callback is what enables the
corresponding capability:
defmodule MyApp.RawMCP do
use Noizu.MCP.Server, name: "raw", version: "1.0.0"
@impl true
def handle_list_tools(_cursor, _ctx),
do: {:ok, [%Noizu.MCP.Types.Tool{name: "echo"}], nil}
@impl true
def handle_call_tool("echo", args, _ctx),
do: {:ok, inspect(args)}
endBehaviour-level handlers receive string-keyed, unvalidated arguments — validation/casting is part of the component DSL layer.
Summary
Callbacks
Execute a tool for tools/call. See Noizu.MCP.Server.Tool for return values.
Complete an argument value for completion/complete.
Render a prompt for prompts/get. See Noizu.MCP.Server.Prompt for return values.
List prompts for prompts/list.
List resource templates for resources/templates/list.
List resources for resources/list.
List tools for tools/list. Return {:ok, tools, next_cursor}.
Read a resource. See Noizu.MCP.Server.Resource for return values.
Approve or reject a resources/subscribe. Return :ok to accept.
Hook for resources/unsubscribe (the runtime updates subscription state regardless).
Per-session initialization, invoked once the handshake completes. Seed
session assigns via Noizu.MCP.Ctx.assign/3 on the returned ctx. Runs in the
session process — keep it fast.
Functions
Register a prompt module (see Noizu.MCP.Server.Prompt).
Register a resource module (see Noizu.MCP.Server.Resource).
Register a resource template module (see Noizu.MCP.Server.ResourceTemplate).
Register a tool module (see Noizu.MCP.Server.Tool). Options: :name, :description overrides.
Callbacks
@callback handle_call_tool(name :: String.t(), args :: map(), Noizu.MCP.Ctx.t()) :: {:ok, term()} | {:error, term()}
Execute a tool for tools/call. See Noizu.MCP.Server.Tool for return values.
@callback handle_complete( ref :: {:prompt, String.t()} | {:resource_template, String.t()}, argument :: {String.t(), String.t()}, Noizu.MCP.Ctx.t() ) :: {:ok, [String.t()]} | {:ok, [String.t()], keyword()} | {:error, Noizu.MCP.Error.t()}
Complete an argument value for completion/complete.
ref is {:prompt, name} or {:resource_template, uri_template};
argument is {name, partial_value}. Return {:ok, values} or
{:ok, values, total: n, has_more: true}.
@callback handle_get_prompt(name :: String.t(), args :: map(), Noizu.MCP.Ctx.t()) :: {:ok, [Noizu.MCP.Types.PromptMessage.t()]} | {:ok, [Noizu.MCP.Types.PromptMessage.t()], keyword()} | {:error, Noizu.MCP.Error.t()}
Render a prompt for prompts/get. See Noizu.MCP.Server.Prompt for return values.
@callback handle_list_prompts(cursor :: String.t() | nil, Noizu.MCP.Ctx.t()) :: {:ok, [Noizu.MCP.Types.Prompt.t()], String.t() | nil} | {:error, Noizu.MCP.Error.t()}
List prompts for prompts/list.
@callback handle_list_resource_templates(cursor :: String.t() | nil, Noizu.MCP.Ctx.t()) :: {:ok, [Noizu.MCP.Types.ResourceTemplate.t()], String.t() | nil} | {:error, Noizu.MCP.Error.t()}
List resource templates for resources/templates/list.
@callback handle_list_resources(cursor :: String.t() | nil, Noizu.MCP.Ctx.t()) :: {:ok, [Noizu.MCP.Types.Resource.t()], String.t() | nil} | {:error, Noizu.MCP.Error.t()}
List resources for resources/list.
@callback handle_list_tools(cursor :: String.t() | nil, Noizu.MCP.Ctx.t()) :: {:ok, [Noizu.MCP.Types.Tool.t()], String.t() | nil} | {:error, Noizu.MCP.Error.t()}
List tools for tools/list. Return {:ok, tools, next_cursor}.
@callback handle_read_resource(uri :: String.t(), Noizu.MCP.Ctx.t()) :: {:ok, term()} | {:error, term()}
Read a resource. See Noizu.MCP.Server.Resource for return values.
@callback handle_subscribe(uri :: String.t(), Noizu.MCP.Ctx.t()) :: :ok | {:error, Noizu.MCP.Error.t()}
Approve or reject a resources/subscribe. Return :ok to accept.
@callback handle_unsubscribe(uri :: String.t(), Noizu.MCP.Ctx.t()) :: :ok | {:error, Noizu.MCP.Error.t()}
Hook for resources/unsubscribe (the runtime updates subscription state regardless).
@callback init(Noizu.MCP.Ctx.t(), init_params :: map()) :: {:ok, Noizu.MCP.Ctx.t()} | {:error, term()}
Per-session initialization, invoked once the handshake completes. Seed
session assigns via Noizu.MCP.Ctx.assign/3 on the returned ctx. Runs in the
session process — keep it fast.
Functions
Register a prompt module (see Noizu.MCP.Server.Prompt).
Register a resource module (see Noizu.MCP.Server.Resource).
Register a resource template module (see Noizu.MCP.Server.ResourceTemplate).
Register a tool module (see Noizu.MCP.Server.Tool). Options: :name, :description overrides.