Hermolaos.Protocol.JsonRpc (Hermolaos v0.3.0)
View SourceJSON-RPC 2.0 encoding and decoding for MCP protocol messages.
This module handles the low-level JSON-RPC 2.0 message format used by MCP. All MCP communication uses JSON-RPC 2.0 as the underlying protocol.
Message Types
- Request: Has
id,method, and optionalparams - Response: Has
idand eitherresultorerror - Notification: Has
methodand optionalparams, but noid
Examples
# Encoding a request
iex> Hermolaos.Protocol.JsonRpc.encode_request(1, "tools/list", %{})
~s({"id":1,"jsonrpc":"2.0","method":"tools/list","params":{}})
# Decoding a response
iex> Hermolaos.Protocol.JsonRpc.decode(~s({"jsonrpc":"2.0","id":1,"result":{"tools":[]}}))
{:ok, {:response, %{"jsonrpc" => "2.0", "id" => 1, "result" => %{"tools" => []}}}}
Summary
Functions
Classifies a decoded JSON-RPC message by its type.
Decodes a JSON-RPC 2.0 message and classifies its type.
Decodes a JSON-RPC 2.0 message, raising on error.
Encodes a JSON-RPC 2.0 error response.
Encodes a JSON-RPC 2.0 notification message (no response expected).
Encodes a JSON-RPC 2.0 request message.
Encodes a JSON-RPC 2.0 success response.
Checks if a response is an error response.
Extracts the error object from an error response.
Extracts the request/response ID from a message.
Extracts the method name from a request or notification.
Extracts parameters from a request or notification.
Extracts the result from a successful response.
Returns the message type of a decoded message.
Validates that a message is a proper JSON-RPC 2.0 notification.
Validates that a message is a proper JSON-RPC 2.0 request.
Validates that a message is a proper JSON-RPC 2.0 response (success or error).
Types
@type decoded_message() :: {message_type(), map()}
@type error_response() :: %{ jsonrpc: String.t(), id: id() | nil, error: error_object() }
@type message_type() :: :request | :notification | :response | :error_response
Functions
@spec classify_message(map()) :: {:ok, decoded_message()} | {:error, :invalid_message}
Classifies a decoded JSON-RPC message by its type.
Examples
iex> Hermolaos.Protocol.JsonRpc.classify_message(%{"jsonrpc" => "2.0", "id" => 1, "method" => "ping"})
{:ok, {:request, %{"jsonrpc" => "2.0", "id" => 1, "method" => "ping"}}}
@spec decode(String.t()) :: {:ok, decoded_message()} | {:error, :parse_error | :invalid_message}
Decodes a JSON-RPC 2.0 message and classifies its type.
Returns {:ok, {type, message}} where type is one of:
:request- A request expecting a response:notification- A notification (no response expected):response- A successful response:error_response- An error response
Examples
iex> Hermolaos.Protocol.JsonRpc.decode(~s({"jsonrpc":"2.0","id":1,"method":"ping"}))
{:ok, {:request, %{"jsonrpc" => "2.0", "id" => 1, "method" => "ping"}}}
iex> Hermolaos.Protocol.JsonRpc.decode(~s({"jsonrpc":"2.0","method":"notifications/initialized"}))
{:ok, {:notification, %{"jsonrpc" => "2.0", "method" => "notifications/initialized"}}}
iex> Hermolaos.Protocol.JsonRpc.decode("invalid json")
{:error, :parse_error}
@spec decode!(String.t()) :: decoded_message()
Decodes a JSON-RPC 2.0 message, raising on error.
Examples
iex> Hermolaos.Protocol.JsonRpc.decode!(~s({"jsonrpc":"2.0","id":1,"result":{}}))
{:response, %{"jsonrpc" => "2.0", "id" => 1, "result" => %{}}}
Encodes a JSON-RPC 2.0 error response.
Parameters
id- The request ID (can be nil if request couldn't be parsed)code- Error code (integer)message- Human-readable error messagedata- Optional additional error data
Examples
iex> Hermolaos.Protocol.JsonRpc.encode_error_response(1, -32600, "Invalid Request")
~s({"error":{"code":-32600,"message":"Invalid Request"},"id":1,"jsonrpc":"2.0"})
Encodes a JSON-RPC 2.0 notification message (no response expected).
Notifications are like requests but without an id field, meaning
the server should not send a response.
Parameters
method- The RPC method nameparams- Optional parameters (map or list)
Examples
iex> Hermolaos.Protocol.JsonRpc.encode_notification("notifications/initialized", %{})
~s({"jsonrpc":"2.0","method":"notifications/initialized","params":{}})
Encodes a JSON-RPC 2.0 request message.
Parameters
id- Unique request identifier (integer or string)method- The RPC method nameparams- Optional parameters (map or list)
Examples
iex> Hermolaos.Protocol.JsonRpc.encode_request(1, "tools/list", %{})
~s({"id":1,"jsonrpc":"2.0","method":"tools/list","params":{}})
iex> Hermolaos.Protocol.JsonRpc.encode_request("abc", "ping", nil)
~s({"id":"abc","jsonrpc":"2.0","method":"ping"})
Encodes a JSON-RPC 2.0 success response.
Parameters
id- The request ID being responded toresult- The result data
Examples
iex> Hermolaos.Protocol.JsonRpc.encode_response(1, %{tools: []})
~s({"id":1,"jsonrpc":"2.0","result":{"tools":[]}})
Checks if a response is an error response.
@spec get_error(map()) :: error_object() | nil
Extracts the error object from an error response.
Extracts the request/response ID from a message.
Examples
iex> Hermolaos.Protocol.JsonRpc.get_id(%{"id" => 42})
42
iex> Hermolaos.Protocol.JsonRpc.get_id(%{"method" => "notify"})
nil
Extracts the method name from a request or notification.
Extracts parameters from a request or notification.
Extracts the result from a successful response.
@spec message_type(map()) :: message_type() | :unknown
Returns the message type of a decoded message.
Examples
iex> Hermolaos.Protocol.JsonRpc.message_type(%{"jsonrpc" => "2.0", "id" => 1, "method" => "ping"})
:request
Validates that a message is a proper JSON-RPC 2.0 notification.
Validates that a message is a proper JSON-RPC 2.0 request.
Examples
iex> Hermolaos.Protocol.JsonRpc.valid_request?(%{"jsonrpc" => "2.0", "id" => 1, "method" => "ping"})
true
iex> Hermolaos.Protocol.JsonRpc.valid_request?(%{"id" => 1, "method" => "ping"})
false
Validates that a message is a proper JSON-RPC 2.0 response (success or error).