Type definitions for the Model Context Protocol.
MCP 2026-07-28 is the latest stable protocol revision. This module holds the shared type surface used across both protocol eras. Version-specific modules document the wire differences for each revision.
Version-specific modules
ExMCP.Types.V20241105— initial stable versionExMCP.Types.V20250326— subscriptions / batch eraExMCP.Types.V20250618— structured tool output; batching removedExMCP.Types.V20251125— tasks, icons, URL elicitation, sampling tool callsExMCP.Types.V20260728— latest stable stateless era, MRTR, discovery, caching
Prefer the documented :protocol_mode client/server option for negotiation
rather than hard-coding version strings in application code.
Unqualified initialize results, roots, sampling, session, and legacy task
types remain here for 1.x source compatibility. For fields that changed on
the wire, use ExMCP.Types.V20260728 as the modern reference instead of
assuming the shared legacy shape applies to MCP 2026-07-28.
Protocol-mode rollout
rc.6 defaults new connections to :prefer_modern, with evidence-based
fallback to legacy peers. The zero-arity legacy compatibility accessor
continues to return 2025-11-25 during the soak and throughout 1.x.
Summary
Functions
Converts a content type atom to a string.
Converts an include context atom to a string.
Returns the newest legacy protocol revision used by compatibility helpers.
Converts a log level atom to a string.
Converts a role atom to a string.
Converts a string content type to an atom.
Converts a string include context to an atom.
Converts a string log level to an atom.
Converts a string role to an atom.
Types
@type atom_initialize_result() :: %{ :protocolVersion => String.t(), :capabilities => server_capabilities(), :serverInfo => server_info(), optional(:instructions) => String.t() }
@type audio_content() :: %{ :type => :audio, :data => String.t(), :mimeType => String.t(), optional(:annotations) => annotations() }
@type cache_scope() :: :public | :private | String.t()
@type cacheable_result() :: %{ optional(:resultType) => String.t(), optional(:ttlMs) => non_neg_integer(), optional(:cacheScope) => cache_scope() }
@type call_tool_result() :: tool_result()
@type cancelled_notification() :: %{ :requestId => request_id(), optional(:reason) => String.t() }
@type client_info() :: implementation()
@type client_notification() :: cancelled_notification() | progress_notification() | list_changed_notification()
@type client_request() :: ping_request() | initialize_request() | list_resources_request() | read_resource_request() | list_prompts_request() | get_prompt_request() | list_tools_request() | call_tool_request() | complete_request() | set_level_request() | subscribe_request() | unsubscribe_request()
@type client_result() :: empty_result() | create_message_result() | list_roots_result() | elicit_result()
@type complete_argument() :: completion_argument()
@type complete_ref() :: completion_reference()
@type complete_request() :: %{ ref: completion_reference(), argument: completion_argument() }
@type complete_result() :: completion_result()
@type completion_reference() :: resource_reference() | prompt_reference()
@type content() :: text_content() | image_content() | audio_content() | embedded_resource()
@type content_type() :: :text | :image | :audio | :resource
@type create_message_params() :: %{ :messages => [sampling_message()], :maxTokens => integer(), optional(:modelPreferences) => model_preferences(), optional(:systemPrompt) => String.t(), optional(:includeContext) => include_context(), optional(:temperature) => float(), optional(:stopSequences) => [String.t()], optional(:metadata) => map(), optional(:tools) => [tool()], optional(:toolChoice) => tool_choice() }
@type create_message_result() :: %{ :role => role(), :content => text_content() | image_content() | audio_content(), :model => String.t(), optional(:stopReason) => String.t() }
@type cursor() :: String.t()
@type elicit_request() :: %{ message: String.t(), requestedSchema: %{ :type => String.t(), :properties => %{required(String.t()) => primitive_schema()}, optional(:required) => [String.t()] } }
@type embedded_resource() :: %{ :type => :resource, :resource => resource_contents(), optional(:annotations) => annotations() }
@type empty_result() :: %{}
@type error_code() :: integer()
@type error_data() :: any()
@type get_prompt_result() :: %{ optional(:description) => String.t(), messages: [prompt_message()] }
@type image_content() :: %{ :type => :image, :data => String.t(), :mimeType => String.t(), optional(:annotations) => annotations() }
@type include_context() :: :none | :thisServer | :allServers
@type initialize_request() :: %{ protocolVersion: String.t(), capabilities: client_capabilities(), clientInfo: client_info() }
@type initialize_result() :: atom_initialize_result() | wire_initialize_result()
@type json_schema() :: map()
@type jsonrpc_error() :: %{ :code => error_code(), :message => String.t(), optional(:data) => error_data() }
@type jsonrpc_error_response() :: %{ jsonrpc: String.t(), id: request_id(), error: jsonrpc_error() }
@type jsonrpc_message() :: jsonrpc_request() | jsonrpc_notification() | jsonrpc_response() | jsonrpc_error_response()
@type jsonrpc_request() :: %{ :jsonrpc => String.t(), :id => request_id(), :method => String.t(), optional(:params) => map() }
@type jsonrpc_response() :: %{jsonrpc: String.t(), id: request_id(), result: any()}
@type list_changed_notification() :: %{}
@type list_prompts_request() :: paginated_request()
@type list_resource_templates_request() :: paginated_request()
@type list_resource_templates_result() :: %{ :resourceTemplates => [resource_template()], optional(:nextCursor) => cursor() }
@type list_resources_request() :: paginated_request()
@type list_roots_request() :: %{}
@type list_roots_result() :: %{roots: [root()]}
@type list_tools_request() :: paginated_request()
@type log_level() ::
:debug | :info | :notice | :warning | :error | :critical | :alert | :emergency
@type log_level_string() :: String.t()
@type log_notification() :: %{ :level => log_level_string(), optional(:logger) => String.t(), data: any() }
@type model_hint() :: %{optional(:name) => String.t()}
@type model_preferences() :: %{ optional(:hints) => [model_hint()], optional(:costPriority) => float(), optional(:speedPriority) => float(), optional(:intelligencePriority) => float() }
@type paginated_request() :: %{optional(:cursor) => cursor()}
@type paginated_result() :: %{optional(:nextCursor) => cursor()}
@type ping_request() :: %{}
@type primitive_schema() :: %{ :type => String.t(), optional(:title) => String.t(), optional(:description) => String.t(), optional(:enum) => [String.t()], optional(:enumNames) => [String.t()], optional(:default) => any(), optional(:minLength) => integer(), optional(:maxLength) => integer(), optional(:minimum) => number(), optional(:maximum) => number(), optional(:format) => String.t() }
@type progress_notification() :: %{ :progressToken => progress_token(), :progress => number(), optional(:total) => number(), optional(:message) => String.t() }
@type prompt_reference() :: %{type: :"ref/prompt", name: String.t()}
@type protocol_mode() :: :legacy_only | :modern_only | :prefer_legacy | :prefer_modern
@type read_resource_request() :: %{uri: String.t()}
@type read_resource_result() :: %{contents: [resource_contents()]}
@type resource_contents() :: text_resource_contents() | blob_resource_contents()
@type resource_reference() :: %{type: :"ref/resource", uri: String.t()}
@type resource_updated_notification() :: %{uri: String.t()}
@type role() :: :user | :assistant
@type role_string() :: String.t()
@type sampling_message() :: %{ role: role(), content: text_content() | image_content() | audio_content() }
@type server_capabilities() :: %{ optional(:experimental) => %{required(String.t()) => map()}, optional(:logging) => %{}, optional(:completions) => %{}, optional(:prompts) => %{optional(:listChanged) => boolean()}, optional(:resources) => %{ optional(:subscribe) => boolean(), optional(:listChanged) => boolean() }, optional(:tools) => %{optional(:listChanged) => boolean()}, optional(:extensions) => %{required(String.t()) => map()} }
@type server_info() :: implementation()
@type server_notification() :: cancelled_notification() | progress_notification() | log_notification() | resource_updated_notification() | list_changed_notification()
@type server_request() :: ping_request() | create_message_params() | list_roots_request() | elicit_request()
@type server_result() :: empty_result() | initialize_result() | complete_result() | get_prompt_result() | list_prompts_result() | list_resource_templates_result() | list_resources_result() | read_resource_result() | call_tool_result() | list_tools_result()
@type set_level_request() :: %{level: log_level_string()}
@type subscribe_request() :: %{uri: String.t()}
@type subscribe_result() :: %{}
@type task() :: %{ :id => String.t(), :state => task_state(), optional(:toolName) => String.t(), optional(:arguments) => map(), optional(:createdAt) => String.t(), optional(:ttl) => integer(), optional(:result) => tool_result(), optional(:metadata) => map() }
@type task_state() :: :working | :input_required | :completed | :failed | :cancelled
@type text_content() :: %{ :type => :text, :text => String.t(), optional(:annotations) => annotations() }
@type tool() :: %{ :name => String.t(), optional(:description) => String.t(), optional(:title) => String.t(), :inputSchema => json_schema(), optional(:outputSchema) => json_schema(), optional(:annotations) => tool_annotations(), optional(:icons) => [icon()], optional(:execution) => map(), optional(:_meta) => map() }
@type tool_choice() :: %{type: String.t()}
@type transport() :: :stdio | :http | module()
@type unsubscribe_request() :: %{uri: String.t()}
@type unsubscribe_result() :: %{}
Functions
@spec content_type_to_string(content_type()) :: String.t()
Converts a content type atom to a string.
@spec include_context_to_string(include_context()) :: String.t()
Converts an include context atom to a string.
@spec latest_protocol_version() :: String.t()
Returns the newest legacy protocol revision used by compatibility helpers.
Converts a log level atom to a string.
Converts a role atom to a string.
@spec string_to_content_type(String.t()) :: content_type()
Converts a string content type to an atom.
@spec string_to_include_context(String.t()) :: include_context()
Converts a string include context to an atom.
Converts a string log level to an atom.
Converts a string role to an atom.