Snodo.Roots (snodo v0.4.1)

Copy Markdown View Source

Builds and validates embedded roots/list requests for MRTR.

SEP-2577 deprecates server-initiated roots listing in MCP 2026-07-28. The method is still defined by the protocol schema and scored by the official conformance runner, so a 2026-07-28 handler may return one as an input request through Snodo.Result.input_required/1, next to elicitation.

list/0 returns a bare input request, without a JSON-RPC envelope. Use response/3 on a retried request to read only the named ListRootsResult. The dialect refuses the request with -32021 when the client has not declared roots. Each root URI must start with file://, as the 2026-07-28 schema requires. The client chooses which roots to reveal, and a root is a claim about the client's file system, not an access grant: check every path an application derives from one against its own authorization.

Summary

Functions

Builds a roots input request.

Reads and validates the named response, ignoring unrelated response IDs.

Checks the request against this request's client capabilities.

Checks that response is a ListRootsResult.

Validates one bare roots input request.

Types

request()

@type request() :: %{required(String.t()) => term()}

response_result()

@type response_result() :: :missing | {:ok, map()} | {:error, Snodo.Error.t()}

Functions

list()

@spec list() :: request()

Builds a roots input request.

response(context, id, request)

@spec response(Snodo.Context.t() | map(), String.t(), request()) :: response_result()

Reads and validates the named response, ignoring unrelated response IDs.

A valid response is a ListRootsResult: a "roots" list whose entries carry a file:// "uri" and an optional "name". Invalid responses return a generic invalid-params error without the submitted data. Additional JSON fields are preserved and ignored. This helper does not authenticate content or trust client-echoed request state.

supported?(request, arg2)

@spec supported?(term(), term()) :: boolean()

Checks the request against this request's client capabilities.

valid_response?(response)

@spec valid_response?(term()) :: boolean()

Checks that response is a ListRootsResult.

That is a "roots" list, possibly empty, whose entries carry a file:// "uri" and an optional "name". Additional JSON fields are allowed. Snodo.Client applies it to what a roots handler returns.

validate_request(request)

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

Validates one bare roots input request.

The schema makes params optional; when present it may carry only _meta, itself an object.