Ragex.MCP.JSON (Ragex v0.37.2)

View Source

Shared JSON helpers for MCP transports.

Both the stdio server (Ragex.MCP.Server) and the Unix socket server (Ragex.MCP.SocketServer) need to turn arbitrary Elixir terms coming out of the tool/resource handlers into something the JSON encoder accepts, and to encode it without raising.

Keeping this logic in one place means both transports produce byte-identical responses for the same handler output, and there is a single spot to fix encoding edge cases.

Summary

Functions

Encodes an already JSON-safe term, falling back to inspect/1 on failure.

Converts an arbitrary Elixir term into a JSON-safe structure.

Encodes a term as JSON, returning {:ok, binary} or {:error, reason}.

Functions

encode_or_inspect(value)

@spec encode_or_inspect(term()) :: String.t()

Encodes an already JSON-safe term, falling back to inspect/1 on failure.

Never raises: if the encoder rejects the value (for example an unsupported map key), the inspected form is returned instead so the client still gets a readable payload.

result_to_json(value)

@spec result_to_json(term()) :: term()

Converts an arbitrary Elixir term into a JSON-safe structure.

  • tuples are rendered with inspect/1 (JSON has no tuple type)
  • lists and maps are converted recursively
  • binary keys are preserved, other keys are stringified
  • invalid UTF-8 binaries are sanitized so the encoder cannot fail on them

safe_json_encode(value)

@spec safe_json_encode(term()) :: {:ok, String.t()} | {:error, term()}

Encodes a term as JSON, returning {:ok, binary} or {:error, reason}.