JSON-RPC 2.0 message construction and MCP protocol versions.
ConduitMCP is dual-era. It speaks MCP 2026-07-28 (the modern era:
version and capabilities travel in every request's _meta, no handshake)
and 2025-11-25 / 2025-06-18 (the legacy era, negotiated by
initialize). supported_versions/0 lists all three, newest first — the
list server/discover advertises. modern_versions/0 and
legacy_versions/0 split it by era; negotiate_version/1 resolves an
initialize request and only ever picks a legacy version.
protocol_version/0 is the preferred legacy version.
Building responses
Helpers success_response/2, error_response/3,4, and notification/2
produce the right wire shape — string-keyed maps with "jsonrpc",
"id", and either "result" or "error". validate_request/1
performs lightweight shape checking on incoming messages.
Error codes
Standard JSON-RPC 2.0 codes and MCP-specific codes are exposed as
delegating functions to ConduitMcp.Errors:
parse_error/0→ -32700invalid_request/0→ -32600method_not_found/0→ -32601invalid_params/0→ -32602internal_error/0→ -32603server_error/0→ -32000 (generic server-defined)task_not_ready/0→ -32004 (legacytasks/resultbefore completion)request_cancelled/0→ -32800 (notifications/cancelled)
Use these instead of hardcoded integers so error code constants stay in one place.
Examples
iex> ConduitMcp.Protocol.success_response(1, %{"value" => 42})
%{"jsonrpc" => "2.0", "id" => 1, "result" => %{"value" => 42}}
iex> ConduitMcp.Protocol.error_response(1, -32601, "no such method")
%{"jsonrpc" => "2.0", "id" => 1, "error" => %{"code" => -32601, "message" => "no such method"}}
Summary
Functions
Creates an error response.
The legacy-era (initialize-negotiated) versions: ["2025-11-25", "2025-06-18"].
Every MCP method the library routes, mapped to its internal name.
The modern-era (per-request _meta) versions: ["2026-07-28"].
Resolves the version an initialize request asks for: the version itself
when it is a legacy version, otherwise nil. A modern version is never
negotiated by initialize; modern clients send it per request instead.
Creates a notification message.
The preferred legacy protocol version, 2025-11-25.
Creates a success response.
Every supported protocol version, newest first: ["2026-07-28", "2025-11-25", "2025-06-18"].
Validates if a message is a valid JSON-RPC 2.0 notification.
Validates if a message is a valid JSON-RPC 2.0 request.
Validates if a message is a JSON-RPC 2.0 response: an id, no method, and
exactly one of result and error.
Types
@type error_response() :: %{ jsonrpc: String.t(), id: json_rpc_id(), error: error_object() }
@type method() :: String.t()
@type request() :: %{ jsonrpc: String.t(), id: json_rpc_id(), method: method(), params: map() | nil }
@type response() :: success_response() | error_response()
@type success_response() :: %{jsonrpc: String.t(), id: json_rpc_id(), result: any()}
Functions
Creates an error response.
@spec legacy_versions() :: [String.t()]
The legacy-era (initialize-negotiated) versions: ["2025-11-25", "2025-06-18"].
Every MCP method the library routes, mapped to its internal name.
Derived from ConduitMcp.Handler's routing table rather than being a second
hand-maintained copy: the previous list was missing six routed methods
(resources/templates/list, all four tasks/*, and
notifications/cancelled).
@spec modern_versions() :: [String.t()]
The modern-era (per-request _meta) versions: ["2026-07-28"].
Resolves the version an initialize request asks for: the version itself
when it is a legacy version, otherwise nil. A modern version is never
negotiated by initialize; modern clients send it per request instead.
Creates a notification message.
@spec protocol_version() :: String.t()
The preferred legacy protocol version, 2025-11-25.
Creates a success response.
@spec supported_versions() :: [String.t()]
Every supported protocol version, newest first: ["2026-07-28", "2025-11-25", "2025-06-18"].
Validates if a message is a valid JSON-RPC 2.0 notification.
Validates if a message is a valid JSON-RPC 2.0 request.
Validates if a message is a JSON-RPC 2.0 response: an id, no method, and
exactly one of result and error.