JSON-RPC 2.0 messages as MCP uses them: requests with a string or integer id, notifications without one, results, errors, and batches (legacy revision 2025-03-26 only).
@type id() :: String.t() | integer()
@type parsed() :: {:request, id(), String.t(), map()} | {:notification, String.t(), map()} | {:response, id(), map()} | {:error_response, id() | nil, map()} | {:batch, [parsed()]} | {:error, :malformed}
@spec code(atom()) :: integer()
@spec error(id() | nil, integer(), String.t(), term()) :: map()
@spec notification(String.t(), map() | nil) :: map()
@spec parse(term()) :: parsed()
@spec request(id(), String.t(), map() | nil) :: map()
@spec result(id(), map()) :: map()