Per-request handler context.
Every server handler receives a %Noizu.MCP.Ctx{} carrying session identity,
the negotiated protocol version, client info/capabilities, and assigns. Use
it to report progress, emit MCP log messages, and check for cooperative
cancellation.
Handlers do not return an updated context — handler invocations run
concurrently per session. assign/3 is local to the current invocation; use
put_session/3 to persist a value into the session's assigns for subsequent
requests.
Summary
Functions
Put a value in this invocation's local assigns.
True when the client cancelled the current request.
Emit a debug MCP log message. See log/4.
Ask the user (via the client) for structured input (elicitation/create).
Emit a error MCP log message. See log/4.
Emit a info MCP log message. See log/4.
Ask the client for its filesystem roots (roots/list).
Emit an MCP notifications/message log entry to the client, filtered by the
level the client set via logging/setLevel. data may be any
JSON-serializable term. Options: :logger (a logical logger name).
Persist a value into the session's assigns so subsequent requests in this session observe it. Serialized through the session process (atomic), but last-write-wins across concurrently running handlers.
Report progress for the current request. Silently no-ops when the client did
not send a progressToken. Options: :total, :message.
Ask the client to sample an LLM completion (sampling/createMessage).
Emit a warning MCP log message. See log/4.
Types
@type t() :: %Noizu.MCP.Ctx{ assigns: map(), cancel_flag: :atomics.atomics_ref() | nil, client_capabilities: map(), client_info: Noizu.MCP.Types.Implementation.t() | nil, progress_token: term() | nil, protocol_version: String.t() | nil, request_id: Noizu.MCP.JsonRpc.id() | nil, server: module(), session: pid() | nil, session_id: String.t() | nil, transport: atom() }
Functions
Put a value in this invocation's local assigns.
True when the client cancelled the current request.
By default the runtime kills the handler task on cancellation, so most handlers never need this; poll it from handlers that must clean up external state at a safe point.
Emit a debug MCP log message. See log/4.
@spec elicit(t(), String.t(), map(), keyword()) :: {:ok, {:accept, map()} | :decline | :cancel} | {:error, term()}
Ask the user (via the client) for structured input (elicitation/create).
requested_schema is a flat-object JSON Schema map (string keys). Returns
{:ok, {:accept, content}}, {:ok, :decline}, or {:ok, :cancel}.
{:ok, {:accept, %{"confirm" => true}}} =
Noizu.MCP.Ctx.elicit(ctx, "Really delete 14 rows?", %{
"type" => "object",
"properties" => %{"confirm" => %{"type" => "boolean"}},
"required" => ["confirm"]
})
Emit a error MCP log message. See log/4.
Emit a info MCP log message. See log/4.
@spec list_roots( t(), keyword() ) :: {:ok, [Noizu.MCP.Types.Root.t()]} | {:error, term()}
Ask the client for its filesystem roots (roots/list).
Emit an MCP notifications/message log entry to the client, filtered by the
level the client set via logging/setLevel. data may be any
JSON-serializable term. Options: :logger (a logical logger name).
Persist a value into the session's assigns so subsequent requests in this session observe it. Serialized through the session process (atomic), but last-write-wins across concurrently running handlers.
Report progress for the current request. Silently no-ops when the client did
not send a progressToken. Options: :total, :message.
Ask the client to sample an LLM completion (sampling/createMessage).
params is the wire-format map: "messages", "maxTokens", and optionally
"systemPrompt", "modelPreferences", "tools"/"toolChoice" (2025-11-25).
Blocks the calling handler task only. Options: :timeout (default 60s).
{:ok, %{"content" => %{"text" => text}}} =
Noizu.MCP.Ctx.sample(ctx, %{
"messages" => [
%{"role" => "user", "content" => %{"type" => "text", "text" => "Summarize: ..."}}
],
"maxTokens" => 500
})
Emit a warning MCP log message. See log/4.