Anubis. Server. Notifier
(anubis_mcp v2.2.0)
Copy Markdown
Sends notifications and server-initiated requests back to the client that
owns frame.
Every callback receives a Anubis.Server.Frame, and every frame carries
the pid of the Session serving it. These helpers use that pid, so they
work from any process: the Session itself, an application process, or
a task spawned inside a tool callback. That last case is why they exist.
Anubis.Server.send_tools_list_changed/0 and its siblings use
send(self(), ...), which is a no-op outside the Session process.
defmodule MyApp.Tools.Reindex do
use Anubis.Server.Component, type: :tool
@impl true
def execute(%{"job" => job}, frame) do
MyApp.Reindex.run(job, fn step ->
Notifier.progress(frame, step.token, step.done, total: step.total)
end)
{:reply, Response.tool("queued"), frame}
end
endNotifications the client may have subscribed to are dropped by the
session when it should not receive them (see
send_resource_updated/3), exactly like their Anubis.Server
counterparts.
See Anubis.Server.Context for session_pid and request_meta, the two
fields these helpers read off the frame.
Summary
Functions
Sends an elicitation/create request.
Sends notifications/log/message. Requires the client to declare the :logging capability.
Sends an arbitrary notification to the client.
Sends notifications/progress.
Sends notifications/prompts/list_changed.
Sends notifications/resources/updated for one resource.
Sends notifications/resources/list_changed.
Sends a roots/list request.
Sends a sampling/createMessage request.
Sends a notifications/tasks/status carrying the current state of a task.
Sends notifications/tools/list_changed.
Types
@type frame() :: Anubis.Server.Frame.t()
A frame handed to a server callback.
Functions
Sends an elicitation/create request.
Asks the user for structured input. requested_schema is validated
before anything goes on the wire, and the session rejects the request if
the client did not declare the elicitation capability. The response
arrives at the server's handle_elicitation/3 callback.
Per the MCP specification, servers MUST NOT use elicitation to request sensitive information (credentials, payment details, anything the user would not type in front of a stranger).
@spec log_message(frame(), Logger.level(), String.t(), map() | nil) :: :ok
Sends notifications/log/message. Requires the client to declare the :logging capability.
Sends an arbitrary notification to the client.
Every helper below is a wrapper over this. Use it directly for notifications Anubis has no typed helper for.
Notifier.notify(frame, "notifications/resources/updated", %{"uri" => uri})
@spec progress(frame(), String.t() | non_neg_integer(), number(), keyword()) :: :ok
Sends notifications/progress.
The token normally comes from the request's own _meta:
Notifier.progress(frame, frame.context.request_meta["progressToken"], 50, total: 100)
@spec prompts_list_changed(frame()) :: :ok
Sends notifications/prompts/list_changed.
@spec resource_updated(frame(), String.t(), DateTime.t() | nil) :: :ok
Sends notifications/resources/updated for one resource.
Subscription-gated: the session drops it unless the client previously
sent resources/subscribe for this URI.
@spec resources_list_changed(frame()) :: :ok
Sends notifications/resources/list_changed.
Sends a roots/list request.
The response arrives at the server's handle_roots/3 callback.
Sends a sampling/createMessage request.
The response arrives at the server's handle_sampling/3 callback.
Sends a notifications/tasks/status carrying the current state of a task.
Looked up in the server's task store. Per spec (2025-11-25) receivers MAY send these; requestors MUST NOT rely on them.
@spec tools_list_changed(frame()) :: :ok
Sends notifications/tools/list_changed.