json_rpc
JSON-RPC 2.0 protocol encoding and decoding library. Provides predicates
for constructing, parsing, classifying, and inspecting JSON-RPC 2.0
messages (requests, notifications, responses, and error responses). Also
provides stream-based message I/O for implementing JSON-RPC clients and
servers, including Content-Length header framing as used by the Language
Server Protocol (LSP) and the Model Context Protocol (MCP). Uses the
json library for JSON parsing and generation.
API documentation
Open the ../../apis/library_index.html#json_rpc link in a web browser.
Loading
To load this library, load the loader.lgt file:
| ?- logtalk_load(json_rpc(loader)).
Testing
To test this library predicates, load the tester.lgt file:
| ?- logtalk_load(json_rpc(tester)).
Usage
Constructing JSON-RPC 2.0 messages
Construct requests, notifications, responses, and error responses:
| ?- json_rpc::request(subtract, [42,23], 1, Request).
Request = {jsonrpc-'2.0', method-subtract, params-[42,23], id-1}.
| ?- json_rpc::notification(update, [1,2,3], Notification).
Notification = {jsonrpc-'2.0', method-update, params-[1,2,3]}.
| ?- json_rpc::response(19, 1, Response).
Response = {jsonrpc-'2.0', result-19, id-1}.
| ?- json_rpc::error_response(-32601, 'Method not found', 1, ErrorResponse).
Standard error constructors
| ?- json_rpc::parse_error(Error).
Error = ...
| ?- json_rpc::invalid_request(Error).
Error = ...
| ?- json_rpc::method_not_found(1, Error).
Error = ...
| ?- json_rpc::invalid_params(1, Error).
Error = ...
| ?- json_rpc::internal_error(1, Error).
Error = ...
Encoding and decoding
| ?- json_rpc::request(subtract, [42,23], 1, Request),
json_rpc::encode(Request, JSON).
JSON = '{"jsonrpc":"2.0","method":"subtract","params":[42,23],"id":1}'.
| ?- json_rpc::decode('{"jsonrpc":"2.0","result":19,"id":1}', Term).
Message classification
| ?- json_rpc::is_request(Message).
...
| ?- json_rpc::is_notification(Message).
...
| ?- json_rpc::is_response(Message).
...
| ?- json_rpc::is_error_response(Message).
...
| ?- json_rpc::is_batch(Messages).
...
Field extraction
| ?- json_rpc::id(Message, Id).
...
| ?- json_rpc::method(Message, Method).
...
| ?- json_rpc::params(Message, Params).
...
| ?- json_rpc::result(Message, Result).
...
| ?- json_rpc::error_code(Message, Code).
...
| ?- json_rpc::error_message(Message, ErrorMessage).
...
| ?- json_rpc::error_data(Message, Data).
...
Stream I/O (client and server API)
Write and read newline-delimited JSON-RPC messages over streams:
| ?- json_rpc::write_message(Output, Message).
...
| ?- json_rpc::read_message(Input, Message).
...
These predicates can be used with any stream, including socket streams
from the sockets library, to implement JSON-RPC clients and servers.
Content-Length framed I/O (LSP/MCP protocols)
Write and read JSON-RPC messages using Content-Length header framing
as defined by the Language Server Protocol (LSP) and the Model Context
Protocol (MCP). Each message is preceded by a
Content-Length: N\r\n\r\n header where N is the byte length of
the JSON body:
| ?- json_rpc::write_framed_message(Output, Message).
...
| ?- json_rpc::read_framed_message(Input, Message).
...
read_framed_message/2 fails at end of stream or if the header is
missing or malformed.
API summary
Message construction
Predicates for building JSON-RPC 2.0 message terms. Requests include an
id for matching responses; notifications do not.
request(+Method, +Params, +Id, --Request)- Construct a requestrequest(+Method, +Id, --Request)- Construct a request with no parametersnotification(+Method, +Params, --Notification)- Construct a notificationnotification(+Method, --Notification)- Construct a notification with no parametersresponse(+Result, +Id, --Response)- Construct a successful responseerror_response(+Code, +Message, +Id, --ErrorResponse)- Construct an error responseerror_response(+Code, +Message, +Data, +Id, --ErrorResponse)- Construct an error response with data
Standard error responses
Convenience predicates for the five standard JSON-RPC 2.0 error codes.
parse_error(--ErrorResponse)- Parse error (-32700)invalid_request(--ErrorResponse)- Invalid request (-32600)method_not_found(+Id, --ErrorResponse)- Method not found (-32601)invalid_params(+Id, --ErrorResponse)- Invalid params (-32602)internal_error(+Id, --ErrorResponse)- Internal error (-32603)
Encoding and decoding
Convert between JSON-RPC message terms and JSON atoms (strings).
encode(+Term, --JSON)- Encode a JSON-RPC term to a JSON atomdecode(+JSON, --Term)- Decode a JSON atom to a JSON-RPC term
Message classification
Test what kind of JSON-RPC message a term represents.
is_request(+Term)- Test if a term is a requestis_notification(+Term)- Test if a term is a notificationis_response(+Term)- Test if a term is a successful responseis_error_response(+Term)- Test if a term is an error responseis_batch(+Term)- Test if a term is a batch (non-empty list)
Field extraction
Extract individual fields from JSON-RPC message terms.
id(+Message, --Id)- Extract the id fieldmethod(+Message, --Method)- Extract the method fieldparams(+Message, --Params)- Extract the params fieldresult(+Message, --Result)- Extract the result fielderror(+Message, --Error)- Extract the error objecterror_code(+Message, --Code)- Extract the error codeerror_message(+Message, --ErrorMessage)- Extract the error messageerror_data(+Message, --Data)- Extract the error data
Stream I/O
Read and write JSON-RPC messages over streams. The newline-delimited variants are suitable for socket-based communication. The Content-Length framed variants implement the header-based framing used by the Language Server Protocol (LSP) and the Model Context Protocol (MCP).
write_message(+Output, +Message)- Write a newline-delimited messageread_message(+Input, --Message)- Read a newline-delimited messagewrite_framed_message(+Output, +Message)- Write a message with Content-Length framingread_framed_message(+Input, --Message)- Read a message with Content-Length framing