MCPEx.Protocol.Capabilities (MCPEx v0.1.0)

Handles protocol capabilities and version negotiation.

This module provides utilities for:

  • Creating client and server capability maps
  • Checking for capability support
  • Negotiating protocol versions
  • Validating capability requirements

The MCP protocol uses capabilities to allow clients and servers to declare which features they support, with both required and optional capabilities.

Summary

Functions

Builds client capabilities map based on provided capabilities list. DEPRECATED: Use create_client_capabilities/1 instead.

Creates a client capabilities object according to the MCP specification.

Creates a server capabilities object according to the MCP specification.

Checks if a specific capability is available.

Gets the latest supported protocol version.

Negotiates a common protocol version between client and server.

Parses server capabilities from an initialize response.

Returns the current protocol version supported by this client.

Gets all supported protocol versions.

Validates that required capabilities are supported.

Functions

build_client_capabilities(capabilities)

@spec build_client_capabilities([atom()]) :: map()

Builds client capabilities map based on provided capabilities list. DEPRECATED: Use create_client_capabilities/1 instead.

create_client_capabilities(options \\ [])

@spec create_client_capabilities(keyword()) :: map()

Creates a client capabilities object according to the MCP specification.

Options

  • sampling - Whether to include sampling capability (default: true)
  • roots - Whether to include roots capability (default: false)
  • roots_list_changed - Whether roots supports list change notifications (default: false)
  • experimental - Optional map of experimental capabilities

Returns

  • map() - The client capabilities object ready for initialization

Examples

iex> MCPEx.Protocol.Capabilities.create_client_capabilities()
%{sampling: %{}}

iex> MCPEx.Protocol.Capabilities.create_client_capabilities(roots: true, roots_list_changed: true)
%{sampling: %{}, roots: %{listChanged: true}}

create_server_capabilities(options \\ [])

@spec create_server_capabilities(keyword()) :: map()

Creates a server capabilities object according to the MCP specification.

Options

  • resources - Whether to include resources capability (default: false)
  • resources_subscribe - Whether resources can be subscribed to (default: false)
  • resources_list_changed - Whether resources supports list change notifications (default: false)
  • tools - Whether to include tools capability (default: false)
  • tools_list_changed - Whether tools supports list change notifications (default: false)
  • prompts - Whether to include prompts capability (default: false)
  • prompts_list_changed - Whether prompts supports list change notifications (default: false)
  • logging - Whether to include logging capability (default: false)
  • experimental - Optional map of experimental capabilities

Returns

  • map() - The server capabilities object

Examples

iex> MCPEx.Protocol.Capabilities.create_server_capabilities(resources: true, resources_subscribe: true)
%{resources: %{subscribe: true}}

has_capability?(capabilities, capability, sub_capability \\ nil)

@spec has_capability?(map(), atom(), atom() | nil) :: boolean()

Checks if a specific capability is available.

Parameters

  • capabilities - The capability map to check
  • capability - The main capability to check for
  • sub_capability - Optional sub-capability to check for

Returns

  • boolean() - true if the capability is available, otherwise false

Examples

iex> capabilities = %{resources: %{subscribe: true}}
iex> MCPEx.Protocol.Capabilities.has_capability?(capabilities, :resources)
true

iex> capabilities = %{resources: %{subscribe: true}}
iex> MCPEx.Protocol.Capabilities.has_capability?(capabilities, :resources, :subscribe)
true

iex> capabilities = %{resources: %{subscribe: true}}
iex> MCPEx.Protocol.Capabilities.has_capability?(capabilities, :sampling)
false

latest_version()

@spec latest_version() :: String.t()

Gets the latest supported protocol version.

Returns

  • String.t() - The latest supported version

negotiate_version(client_versions, server_versions)

@spec negotiate_version(String.t() | [String.t()], [String.t()]) ::
  {:ok, String.t()} | {:error, String.t()}

Negotiates a common protocol version between client and server.

Parameters

  • client_versions - Client supported version(s)
  • server_versions - Server supported version(s)

Returns

  • {:ok, version} - The negotiated common version
  • {:error, reason} - Error when no common version exists

Examples

iex> client_version = "2025-03-26"
iex> server_versions = ["2025-03-26", "2024-11-05"]
iex> MCPEx.Protocol.Capabilities.negotiate_version(client_version, server_versions)
{:ok, "2025-03-26"}

parse_server_capabilities(server_capabilities)

@spec parse_server_capabilities(map()) :: {:ok, map()} | {:error, String.t()}

Parses server capabilities from an initialize response.

Parameters

  • response - The initialization response from the server

Returns

  • {:ok, capabilities} - The parsed server capabilities
  • {:error, reason} - Error parsing capabilities

protocol_version()

@spec protocol_version() :: String.t()

Returns the current protocol version supported by this client.

supported_versions()

@spec supported_versions() :: [String.t()]

Gets all supported protocol versions.

Returns

  • [String.t()] - List of supported versions

validate_capability_support(required_capabilities, available_capabilities)

@spec validate_capability_support([atom()], map()) :: :ok | {:error, String.t()}

Validates that required capabilities are supported.

Parameters

  • required_capabilities - List of capability atoms that are required
  • available_capabilities - Map of capabilities that are available

Returns

  • :ok - All required capabilities are available
  • {:error, reason} - Some required capabilities are missing

Examples

iex> MCPEx.Protocol.Capabilities.validate_capability_support(
...>   [:sampling], 
...>   %{resources: %{}, sampling: %{}}
...> )
:ok