Anubis.Telemetry (anubis_mcp v2.2.0)

Copy Markdown

Telemetry events emitted by Anubis.

Every event is namespaced under [:anubis_mcp | event]. The client emits them, the server emits them, and the transports emit their own.

Attaching handlers

:telemetry.attach_many(
  "anubis-metrics",
  [
    [:anubis_mcp, :server, :request],
    [:anubis_mcp, :server, :tool_call, :stop]
  ],
  &MyApp.Metrics.handle_event/4,
  %{}
)

Events

Most events carry %{system_time: System.system_time()} as their only measurement; the interesting payload is in the metadata. The :response and :error events also carry %{duration: elapsed_ms}.

Client

EventMetadata
[:anubis_mcp, :client, :init]client_name, transport, protocol_version, capabilities
[:anubis_mcp, :client, :request]method, request_id
[:anubis_mcp, :client, :response]id, method, status, transport
[:anubis_mcp, :client, :notification]method, uri
[:anubis_mcp, :client, :error]id, method, error
[:anubis_mcp, :client, :terminate]client_name, reason, pending_requests
[:anubis_mcp, :client, :roots]action, request_id

Server

EventMetadata
[:anubis_mcp, :server, :init]session_id, capabilities, server_info, module
[:anubis_mcp, :server, :request]id
[:anubis_mcp, :server, :response]id, method, level
[:anubis_mcp, :server, :notification]method, server_module, started_at
[:anubis_mcp, :server, :error]id, error, message, session_id, stateless
[:anubis_mcp, :server, :terminate]reason

Tool calls

[:anubis_mcp, :server, :tool_call] is a :telemetry.span/3, so it emits :start, :stop and :exception events. See span_tool_call/3.

Authorization

[:anubis_mcp, :server, :authorization] is a :telemetry.span/3 wrapping the Streamable HTTP bearer authorization flow, so it emits :start, :stop and :exception events. See span_authorization/2. The :stop metadata carries outcome, one of :ok, :missing_token, :invalid_token, :invalid_issuer, :invalid_audience, :token_expired, :invalid_expiry, :validator_unavailable, :other. Authorization metadata never includes tokens, claims, or raw validator error reasons.

EventMetadata
[:anubis_mcp, :server, :authorization, :start]validator
[:anubis_mcp, :server, :authorization, :stop]validator, outcome
[:anubis_mcp, :server, :authorization, :exception]validator, kind, reason, stacktrace
[:anubis_mcp, :server, :authorization, :validate] (deprecated)validator

Transport

Transport events always carry transport (the layer, e.g. :stdio or :streamable_http). The rest varies by transport:

EventMetadata
[:anubis_mcp, :transport, :init]transport, client, io_device
[:anubis_mcp, :transport, :connect]transport, client
[:anubis_mcp, :transport, :send]transport, client
[:anubis_mcp, :transport, :receive]transport, client, message_size
[:anubis_mcp, :transport, :disconnect]transport, client, reason
[:anubis_mcp, :transport, :terminate]transport, client, reason
[:anubis_mcp, :transport, :error]transport, client, error
[:anubis_mcp, :transport, :sse_handler, :registered]session_id, handler_pid, handler_count (measurement)

Treat metadata as open: new keys may be added, so match on the ones you need and ignore the rest.

Summary

Functions

event_client_error()

event_client_init()

event_client_notification()

event_client_request()

event_client_response()

event_client_roots()

event_client_terminate()

event_server_authorization()

event_server_authorization_validate()

Deprecated single-shot event emitted before the validator runs.

Superseded by the [:server, :authorization] span: the :stop event's bounded outcome reports whether validation succeeded and why it failed. Kept during a deprecation window; attach handlers to the span instead.

event_server_error()

event_server_init()

event_server_notification()

event_server_request()

event_server_response()

event_server_terminate()

event_server_tool_call()

event_transport_connect()

event_transport_disconnect()

event_transport_error()

event_transport_init()

event_transport_receive()

event_transport_send()

event_transport_sse_handler_registered()

event_transport_terminate()

execute(event_name, measurements, metadata)

@spec execute([atom()], map(), map()) :: :ok

Execute a telemetry event with the Anubis MCP namespace.

Parameters

  • event_name - List of atoms for the event name, excluding the :anubis_mcp prefix
  • measurements - Map of measurements for the event
  • metadata - Map of metadata for the event

span_authorization(start_metadata, fun)

@spec span_authorization(map(), (-> {result, Anubis.Server.Authorization.outcome()})) ::
  result
when result: var

Wraps a bearer authorization flow in the [:server, :authorization] telemetry span.

Emits :start, :stop and :exception events under [:anubis_mcp, :server, :authorization]. The start_metadata map (typically %{validator: module}) is used for the :start event and, with outcome added, for the :stop event. The :stop measurements carry duration.

The fun returns {result, outcome} where outcome must be drawn from the bounded set in Anubis.Server.Authorization.outcome/1. Tokens, claims, and raw validator error reasons must not be added to the metadata.

Examples

Telemetry.span_authorization(%{validator: MyValidator}, fn ->
  {{:ok, conn, claims}, :ok}
end)

span_tool_call(tool_name, arguments, fun)

@spec span_tool_call(String.t() | nil, map() | nil, (-> result)) :: result
when result: var

Wraps a tool call handler invocation in the [:server, :tool_call] telemetry span.

Shared by the synchronous scheduler dispatch and the task-augmented tools/call worker path so both surface identical span data regardless of which route a given request took.

The span's :start metadata always carries tool; the :stop metadata always carries tool and is_error. When :telemetry_capture_tool_payload is enabled (defaults to false), the :start metadata also carries arguments and the :stop metadata also carries result. See pages/testing.md for the rationale behind the opt-in default.

Examples

iex> Anubis.Telemetry.span_tool_call("get_weather", %{"city" => "NYC"}, fn -> :ok end)
:ok