Anubis. Protocol. Registry
(anubis_mcp v2.2.0)
Copy Markdown
Registry for MCP protocol version modules.
Maps version strings to their implementing modules, supports version negotiation, and provides the central dispatch point for version-specific protocol logic.
Eras
Registered versions group into the eras defined by
Anubis.Protocol.Behaviour — :legacy versions negotiate a session with
the initialize handshake, :stateless versions carry their metadata on
every request. The grouping is derived from each module's Anubis.Protocol.Behaviour.era/0
callback, so registering a version is still a single entry in @versions.
Because the two eras open a connection in structurally different ways, they
negotiate separately: negotiate/1 and negotiate/2 serve the initialize
handshake and therefore only ever resolve to a :legacy version.
Usage
iex> Anubis.Protocol.Registry.get("2025-11-25")
{:ok, Anubis.Protocol.V2025_11_25}
iex> Anubis.Protocol.Registry.supported_versions()
["2026-07-28", "2025-11-25", "2025-06-18", "2025-03-26"]
iex> Anubis.Protocol.Registry.versions_for_era(:stateless)
["2026-07-28"]
iex> Anubis.Protocol.Registry.negotiate("2025-03-26")
{:ok, "2025-03-26", Anubis.Protocol.V2025_03_26}
Summary
Functions
Returns the era a version belongs to.
Returns the fallback protocol version for compatibility.
Get the protocol module for a given version string.
Returns the features supported by a given version.
Returns the module for the latest supported protocol version.
Returns the module for the latest supported version of an era, or nil when
the era has no registered version.
Returns the latest protocol version reachable through the initialize
handshake.
Returns the latest supported version of an era, or nil when none is
registered.
List the versions that negotiate a session with the initialize handshake.
Negotiate the best version given a client's requested version.
Negotiate version between client and server supported version lists.
Returns the progress notification params schema for a given version.
List the versions that carry their metadata on every request.
Check if a version string is supported.
List all supported versions in preference order (newest first).
Checks if a feature is supported by a protocol version.
List the versions belonging to an era, in preference order (newest first).
Types
@type era() :: Anubis.Protocol.Behaviour.era()
@type version() :: String.t()
Functions
Returns the era a version belongs to.
Examples
iex> Anubis.Protocol.Registry.era("2026-07-28")
{:ok, :stateless}
iex> Anubis.Protocol.Registry.era("unknown")
:error
@spec fallback_version() :: version()
Returns the fallback protocol version for compatibility.
Get the protocol module for a given version string.
Examples
iex> Anubis.Protocol.Registry.get("2025-06-18")
{:ok, Anubis.Protocol.V2025_06_18}
iex> Anubis.Protocol.Registry.get("unknown")
:error
Returns the features supported by a given version.
Delegates to the version module's supported_features/0 callback.
@spec latest_module() :: module()
Returns the module for the latest supported protocol version.
Returns the module for the latest supported version of an era, or nil when
the era has no registered version.
Examples
iex> Anubis.Protocol.Registry.latest_module(:stateless)
Anubis.Protocol.V2026_07_28
@spec latest_version() :: version()
Returns the latest protocol version reachable through the initialize
handshake.
Stateless versions are not handshake-negotiable; use latest_version/1 to
ask for the newest version of a specific era.
Returns the latest supported version of an era, or nil when none is
registered.
Examples
iex> Anubis.Protocol.Registry.latest_version(:stateless)
"2026-07-28"
@spec legacy_versions() :: [version()]
List the versions that negotiate a session with the initialize handshake.
Examples
iex> Anubis.Protocol.Registry.legacy_versions()
["2025-11-25", "2025-06-18", "2025-03-26"]
@spec negotiate(version()) :: {:ok, version(), module()} | {:error, :unsupported_version, [version()]}
Negotiate the best version given a client's requested version.
MCP spec: the server picks the version, the client proposes one. If we support the requested version, use it. Otherwise, return an error with the list of supported versions.
This serves the initialize handshake, so it only resolves to :legacy
versions — a stateless version requested here is treated as unsupported.
Examples
iex> Anubis.Protocol.Registry.negotiate("2025-11-25")
{:ok, "2025-11-25", Anubis.Protocol.V2025_11_25}
iex> Anubis.Protocol.Registry.negotiate("9999-01-01")
{:error, :unsupported_version, ["2025-11-25", "2025-06-18", "2025-03-26"]}
iex> Anubis.Protocol.Registry.negotiate("2026-07-28")
{:error, :unsupported_version, ["2025-11-25", "2025-06-18", "2025-03-26"]}
Negotiate version between client and server supported version lists.
Used when the server has a restricted set of supported versions. Returns the client's preference when the server offers it, otherwise the newest legacy version the server offers, regardless of the order they were given in.
Non-legacy and unregistered entries are ignored, and a server list that
offers no legacy version returns :error rather than silently substituting
another version.
Unlike negotiate/1, which is an admission gate and rejects anything it
cannot match exactly, this is the initialize fallback: a client proposing a
version the server does not offer — including a :stateless one — is answered
with the newest legacy version available, as the legacy lifecycle requires
("otherwise, the server MUST respond with another protocol version it
supports"). The client then accepts that version or disconnects.
Examples
iex> Anubis.Protocol.Registry.negotiate("2025-03-26", ["2025-11-25", "2025-03-26"])
{:ok, "2025-03-26", Anubis.Protocol.V2025_03_26}
iex> Anubis.Protocol.Registry.negotiate("2025-06-18", ["2025-11-25", "2025-03-26"])
{:ok, "2025-11-25", Anubis.Protocol.V2025_11_25}
iex> Anubis.Protocol.Registry.negotiate("2025-06-18", ["2025-03-26", "2025-11-25"])
{:ok, "2025-11-25", Anubis.Protocol.V2025_11_25}
iex> Anubis.Protocol.Registry.negotiate("2026-07-28", ["2025-11-25"])
{:ok, "2025-11-25", Anubis.Protocol.V2025_11_25}
iex> Anubis.Protocol.Registry.negotiate("2026-07-28", ["2026-07-28"])
:error
Returns the progress notification params schema for a given version.
Delegates to the version module's progress_params_schema/0 callback.
@spec stateless_versions() :: [version()]
List the versions that carry their metadata on every request.
Examples
iex> Anubis.Protocol.Registry.stateless_versions()
["2026-07-28"]
Check if a version string is supported.
@spec supported_versions() :: [version()]
List all supported versions in preference order (newest first).
Checks if a feature is supported by a protocol version.
List the versions belonging to an era, in preference order (newest first).
Examples
iex> Anubis.Protocol.Registry.versions_for_era(:stateless)
["2026-07-28"]