Armature.MCP.Analytics (armature_mcp_analytics v0.1.0)

Copy Markdown View Source

Community-maintained, framework-neutral Armature analytics instrumentation for MCP servers.

This package is unofficial and is not affiliated with or endorsed by Armature.

The module decorates JSON-style MCP tool definitions, removes Armature's optional telemetry argument before a tool handler runs, and records the result without allowing analytics delivery failures to break the handler.

Add the recorder to your supervision tree:

children = [
  {Armature.MCP.Analytics,
   api_key: System.get_env("ANALYTICS_INGEST_API_KEY"),
   ingest_url: System.get_env("ANALYTICS_INGEST_URL"),
   delivery: :background}
]

Then decorate tools and wrap dispatch:

tools = Armature.MCP.Analytics.decorate_tools(tools)

Armature.MCP.Analytics.track("lookup", arguments, context, fn clean_arguments ->
  lookup(clean_arguments)
end)

context may contain :actor_seed, :session_id, :client_info, :client_capabilities, :protocol_version, :request_meta, and a genuine per-invocation :request_id. Do not use a JSON-RPC message id as the request id because those counters are commonly reused across sessions.

Summary

Functions

Decorates MCP tool definitions with telemetry and, by default, unmet-demand reporting.

Flushes queued background events.

Removes and normalizes Armature telemetry from raw MCP arguments.

Records one MCP session initialization event.

Starts an analytics recorder.

Runs a tool handler with clean arguments and records its outcome.

Types

context()

@type context() :: %{
  optional(:actor_seed) => term(),
  optional(:session_id) => String.t(),
  optional(:client_info) => map(),
  optional(:client_capabilities) => map(),
  optional(:protocol_version) => String.t(),
  optional(:request_meta) => map(),
  optional(:request_id) => String.t()
}

Functions

decorate_tools(tools, opts \\ [])

@spec decorate_tools(
  [map()],
  keyword()
) :: [map()]

Decorates MCP tool definitions with telemetry and, by default, unmet-demand reporting.

flush(server \\ Recorder)

@spec flush(GenServer.server()) :: :ok

Flushes queued background events.

prepare_arguments(arguments, tool_definition \\ nil)

@spec prepare_arguments(map(), map() | nil) :: {map(), map()}

Removes and normalizes Armature telemetry from raw MCP arguments.

record_session(server \\ Recorder, context)

@spec record_session(GenServer.server(), context()) :: :ok

Records one MCP session initialization event.

start_link(opts)

@spec start_link(keyword()) :: GenServer.on_start()

Starts an analytics recorder.

track(server \\ Recorder, tool_name, raw_arguments, context \\ %{}, handler)

@spec track(GenServer.server(), String.t(), map(), context(), (map() -> result)) ::
  result
when result: term()

Runs a tool handler with clean arguments and records its outcome.

The handler's return value and exception behavior are preserved. Analytics errors are reported through the recorder's :on_error callback and never replace the tool result.